Consuming CSV data
CSV 파일 포멧은 plain 텍스트로 테이블 형태의 데이터를 저장하는 자주 사용되는 포멧이다.
아래 예제는 타이타닉 데이터셋을 로드하여 csv 포멧으로 읽는 것을 보여준다.
titanic_file = tf.keras.utils.get_file("train.csv", "https://storage.googleapis.com/tf-datasets/titanic/train.csv") df = pd.read_csv(titanic_file, index_col=None) df.head() |
survived | sex | age | n_siblings_spouses | parch | fare | class | deck | embark_town | alone | |
0 | 0 | male | 22.0 | 1 | 1 | 0 | 7.2500 | Third | Southampton | n |
1 | 1 | female | 38.0 | 1 | 1 | 0 | 71.2833 | First | Cherbourg | n |
2 | 1 | female | 26.0 | 0 | 0 | 0 | 7.9250 | Third | Southampton | y |
3 | 1 | female | 35.0 | 1 | 1 | 0 | 53.1000 | First | Southampton | n |
4 | 0 | male | 28.0 | 0 | 0 | 0 | 8.4583 | Third | Cherbourg | y |
데이터가 메모리에 로딩 가능하다면, Dataset.from_tensor_slices method는 디렉토리에서 도작하고 이 데이터가 쉽게 import되어지게 한다.
titanic_slices = tf.data.Dataset.from_tensor_slices(dict(df)) for feature_batch in titanic_slices.take(1): for key, value in feature_batch.items(): print(" {!r:20s}: {}".format(key, value)) |
>>> print문 내 {!r:20s}에서 !r은 작은 따옴표(')를 출력하게 함.
'survived' : 0 'sex' : b'male' 'age' : 22.0 'n_siblings_spouses': 1 'parch' : 0 'fare' : 7.25 'class' : b'Third' 'deck' : b'unknown' 'embark_town' : b'Southampton' 'alone' : b'n' |
위 방법보다 더 유연한 접근 방법은 필요시 디스크로부터 데이터를 로드하는 것이다.
tf.data 모듈은 RFC 4180 (CSV 파일 규격) 을 따르는 하나이상의 CSV 파일에서 레코드를 추출하기 위한 방법을 제공한다.
experimental.make_csv_dataset 함수는 CSV 파일을 읽기위한 고수준 인터페이스이다. 이것은 간단한 사용을 위해 batch, shuffle같은 다른 많은 특성과 column type 추론(inference)를 지원한다.
titanic_batches = tf.data.experimental.make_csv_dataset(titanic_file, batch_size=4, label_name="survived") for feature_batch, label_batch in titanic_batches.take(1): |
'survived': [1 0 0 0] features: 'sex' : [b'male' b'male' b'male' b'male'] 'age' : [25. 28. 31. 47.] 'n_siblings_spouses': [1 0 1 0] 'parch' : [0 0 1 0] 'fare' : [ 7.775 9.5 37.0042 34.0208] 'class' : [b'Third' b'Third' b'Second' b'First'] 'deck' : [b'unknown' b'unknown' b'unknown' b'D'] 'embark_town' : [b'Southampton' b'Southampton' b'Cherbourg' b'Southampton'] 'alone' : [b'n' b'y' b'n' b'y'] |
만약 데이터셋의 일부 서브셋만이 필요하다면, select_columns를 사용하면 된다.
titanic_batches = tf.data.experimental.make_csv_dataset(titanic_file, batch_size=4,
for feature_batch, label_batch in titanic_batches.take(1): |
'survived': [0 1 0 1] 'fare' : [ 7.2292 53.1 27.7208 20.575 ] 'class' : [b'Third' b'First' b'Second' b'Third'] |
더 세부적으로 제어할 수 있는 저수준의 experimental.CsvDataset도 있다. 이것은 column 타입 추론을 제공하지 않아 각 컬럼의 타입을 명시해야 한다.
titanic_types = [tf.int32, tf.string, tf.float32, tf.int32, tf.int32, tf.float32, tf.string, tf.string, tf.string, tf.string] dataset = tf.data.experimental.CsvDataset(titanic_file, titanic_types , header=True) for line in dataset.take(10): print([item.numpy() for item in line]) |
[0, b'male', 22.0, 1, 0, 7.25, b'Third', b'unknown', b'Southampton', b'n'] [1, b'female', 38.0, 1, 0, 71.2833, b'First', b'C', b'Cherbourg', b'n'] [1, b'female', 26.0, 0, 0, 7.925, b'Third', b'unknown', b'Southampton', b'y'] [1, b'female', 35.0, 1, 0, 53.1, b'First', b'C', b'Southampton', b'n'] [0, b'male', 28.0, 0, 0, 8.4583, b'Third', b'unknown', b'Queenstown', b'y'] [0, b'male', 2.0, 3, 1, 21.075, b'Third', b'unknown', b'Southampton', b'n'] [1, b'female', 27.0, 0, 2, 11.1333, b'Third', b'unknown', b'Southampton', b'n'] [1, b'female', 14.0, 1, 0, 30.0708, b'Second', b'unknown', b'Cherbourg', b'n'] [1, b'female', 4.0, 1, 1, 16.7, b'Third', b'G', b'Southampton', b'n'] [0, b'male', 20.0, 0, 0, 8.05, b'Third', b'unknown', b'Southampton', b'y'] |
만약 데이터셋의 일부 컬럼의 값이 비어있다면, CsvDataset 인터페이스는 컬럼의 타입 대신 기본값을 설정할 수 있다.
우선 테스트 CSV 파일을 작성한다.
%%writefile missing.csv 1,2,3,4 ,2,3,4 1,,3,4 1,2,,4 1,2,3, ,,, |
Writing missing.csv |
# Creates a dataset that reads all of the records from two CSV files, each with # four float columns which may have missing values. record_defaults = [999,999,999,999] dataset = tf.data.experimental.CsvDataset("missing.csv", record_defaults) dataset = dataset.map(lambda *items: tf.stack(items)) dataset |
<MapDataset shapes: (4,), types: tf.int32 |
for line in dataset: print(line.numpy()) |
[1 2 3 4] [999 2 3 4] [ 1 999 3 4] [ 1 2 999 4] [ 1 2 3 999] [999 999 999 999] |
기본적으로 CsvDataset은 파일의 각 라인에 대한 각 컬럼을 모두 만든다. 하지만, 헤드라인으로 시작하거나, 몇몇 불필요한 컬럼이 포함된 경우, 라인과 컬럼을 각각 header와 select_cols 인자로 제거할 수 있다.
# Creates a dataset that reads all of the records from two CSV files with # headers, extracting float data from columns 2 and 4. record_defaults = [999, 999] # Only provide defaults for the selected columns dataset = tf.data.experimental.CsvDataset("missing.csv", record_defaults, select_cols=[1, 3]) dataset = dataset.map(lambda *items: tf.stack(items)) dataset |
<MapDataset shapes: (2,), types: tf.int32> |
for line in dataset: print(line.numpy()) |
[2 4] [2 4] [999 4] [2 4] [ 2 999] [999 999] |