pandasでcsv/tsvファイル読み込み(read_csv, read_table)
csvファイル、tsvファイルをpandas.DataFrame
として読み込むには、pandasの関数read_csv()
かread_table()
を使う。
ここでは、
read_csv()
とread_table()
の違い- headerがないcsvの読み込み
- headerがあるcsvの読み込み
- indexがあるcsvの読み込み
- 列を指定(選択)して読み込み
- 行をスキップ(除外)して読み込み
- 型
dtype
を指定して読み込み - 欠損値
NaN
の扱い - エンコーディングの指定
- zipなどで圧縮されたファイルの読み込み
- Web上のファイルの読み込み
- tsvの読み込み
について説明する。
csvファイルの書き出しや追記については以下の記事を参照。
そのほかpandasでのExcelファイル、jsonファイル、pickleファイルの読み書き(入出力)については以下の記事を参照。
- 関連記事: pandasでExcelファイル(xlsx, xls)の読み込み(read_excel)
- 関連記事: pandasでExcelファイル(xlsx, xls)の書き込み(to_excel)
- 関連記事: pandasでJSON文字列・ファイルを読み込み(read_json)
- 関連記事: pandas.DataFrameをJSON文字列・ファイルに変換・保存(to_json)
- 関連記事: pandas.DataFrame, Seriesをpickleで保存、読み込み(to_pickle, read_pickle)
read_csvとread_tableの違い
pandasの関数pd.read_csv()
とpd.read_table()
はデフォルトの区切り文字が違うだけで中身は同じ。
read_csv()
は区切り文字がカンマ,
でread_table()
は区切り文字がタブ\t
。
ソースを見ると同じ関数を呼び出している。
read_csv = _make_parser_function('read_csv', sep=',')
read_csv = Appender(_read_csv_doc)(read_csv)
read_table = _make_parser_function('read_table', sep='\t')
read_table = Appender(_read_table_doc)(read_table)
csvファイル(カンマ区切り)を読みたいときはread_csv()
、tsvファイル(タブ区切り)を読みたいときはread_table()
でOK。
カンマでもタブでもない場合、引数(sep
かdelimiter
)で区切り文字を設定できる。
以下、read_csv()
で説明するが、read_table
でも同じ。
headerがないcsvの読み込み
headerがない以下のようなcsvファイルを読み込む。
11,12,13,14
21,22,23,24
31,32,33,34
パスは絶対パスかカレントディレクトリ(作業ディレクトリ)からの相対パスで指定する。カレントディレクトリの確認や変更については以下の記事を参照。
なにも引数を設定しないと、1行目がheaderとして認識される。
import pandas as pd
df = pd.read_csv('data/src/sample.csv')
print(df)
# 11 12 13 14
# 0 21 22 23 24
# 1 31 32 33 34
print(df.columns)
# Index(['11', '12', '13', '14'], dtype='object')
header=None
とするとpandasが勝手に列名を割り当ててくれる。
df_none = pd.read_csv('data/src/sample.csv', header=None)
print(df_none)
# 0 1 2 3
# 0 11 12 13 14
# 1 21 22 23 24
# 2 31 32 33 34
names=('A', 'B', 'C', 'D')
のように任意の値を列名として設定することもできる。リストまたはタプルで指定する。
df_names = pd.read_csv('data/src/sample.csv', names=('A', 'B', 'C', 'D'))
print(df_names)
# A B C D
# 0 11 12 13 14
# 1 21 22 23 24
# 2 31 32 33 34
headerがあるcsvの読み込み
headerがある以下のようなcsvファイルを読み込む。
a,b,c,d
11,12,13,14
21,22,23,24
31,32,33,34
header=0
のようにheaderの行番号を0始まりで指定する。デフォルトがheader=0
なので、最初の行がheaderの場合は省略しても同じ結果。
df_header = pd.read_csv('data/src/sample_header.csv')
print(df_header)
# a b c d
# 0 11 12 13 14
# 1 21 22 23 24
# 2 31 32 33 34
df_header_0 = pd.read_csv('data/src/sample_header.csv', header=0)
print(df_header_0)
# a b c d
# 0 11 12 13 14
# 1 21 22 23 24
# 2 31 32 33 34
header
で指定した行からデータが読み込まれ、それより上の行は無視される。
df_header_2 = pd.read_csv('data/src/sample_header.csv', header=2)
print(df_header_2)
# 21 22 23 24
# 0 31 32 33 34
indexがあるcsvの読み込み
headerとindex(見出し列)がある以下のようなcsvファイルを読み込む。
,a,b,c,d
ONE,11,12,13,14
TWO,21,22,23,24
THREE,31,32,33,34
何も指定しないと特にindex列は認識されない。
df_header_index = pd.read_csv('data/src/sample_header_index.csv')
print(df_header_index)
# Unnamed: 0 a b c d
# 0 ONE 11 12 13 14
# 1 TWO 21 22 23 24
# 2 THREE 31 32 33 34
print(df_header_index.index)
# RangeIndex(start=0, stop=3, step=1)
index_col=0
のようにindexとして使いたい列の列番号を0始まりで指定する。
df_header_index_col = pd.read_csv('data/src/sample_header_index.csv', index_col=0)
print(df_header_index_col)
# a b c d
# ONE 11 12 13 14
# TWO 21 22 23 24
# THREE 31 32 33 34
print(df_header_index_col.index)
# Index(['ONE', 'TWO', 'THREE'], dtype='object')
列を指定(選択)して読み込み
引数usecols
特定の列だけを読み込む場合、引数usecols
を使う。
読み込む列番号をリストで指定する。一列だけの場合もリストを使う。
df_none_usecols = pd.read_csv('data/src/sample.csv', header=None, usecols=[1, 3])
print(df_none_usecols)
# 1 3
# 0 12 14
# 1 22 24
# 2 32 34
df_none_usecols = pd.read_csv('data/src/sample.csv', header=None, usecols=[2])
print(df_none_usecols)
# 2
# 0 13
# 1 23
# 2 33
列番号ではなく列名で指定することもできる。
df_header_usecols = pd.read_csv('data/src/sample_header.csv', usecols=['a', 'c'])
print(df_header_usecols)
# a c
# 0 11 13
# 1 21 23
# 2 31 33
特定の列を除外して読み込む場合、無名関数(ラムダ式)を使うと便利。特に列数が多いファイルから少数の列を除外して読み込みたいたいときは読み込む列番号を大量に指定するより楽。
df_header_usecols = pd.read_csv('data/src/sample_header.csv',
usecols=lambda x: x is not 'b')
print(df_header_usecols)
# a c d
# 0 11 13 14
# 1 21 23 24
# 2 31 33 34
df_header_usecols = pd.read_csv('data/src/sample_header.csv',
usecols=lambda x: x not in ['a', 'c'])
print(df_header_usecols)
# b d
# 0 12 14
# 1 22 24
# 2 32 34
index_col
と合わせて使う場合はindex_col
で指定する列もusecols
で指定しておく必要がある。
df_index_usecols = pd.read_csv('data/src/sample_header_index.csv',
index_col=0, usecols=[0, 1, 3])
print(df_index_usecols)
# a c
# ONE 11 13
# TWO 21 23
# THREE 31 33
行をスキップ(除外)して読み込み
引数skiprows
特定の行をスキップ(除外)して読み込む場合、引数skiprows
を使う。
skiprows
に整数を渡すと、ファイルの先頭をその行数分スキップして読み込む。
df_none = pd.read_csv('data/src/sample.csv', header=None)
print(df_none)
# 0 1 2 3
# 0 11 12 13 14
# 1 21 22 23 24
# 2 31 32 33 34
df_none = pd.read_csv('data/src/sample.csv', header=None, skiprows=2)
print(df_none)
# 0 1 2 3
# 0 31 32 33 34
スキップする行番号をリストで指定することもできる。usecols
とは違って、指定するのは読み込む行ではなくスキップする行。
一行だけの場合もリストを使う。
df_none_skiprows = pd.read_csv('data/src/sample.csv', header=None, skiprows=[0, 2])
print(df_none_skiprows)
# 0 1 2 3
# 0 21 22 23 24
df_none_skiprows = pd.read_csv('data/src/sample.csv', header=None, skiprows=[1])
print(df_none_skiprows)
# 0 1 2 3
# 0 11 12 13 14
# 1 31 32 33 34
特定の行だけを読み込む場合は、無名関数(ラムダ式)を使うと便利。特に行数が多いファイルから特定の行だけを読み込みたいたいときはスキップする行番号を指定するより楽。
df_none_skiprows = pd.read_csv('data/src/sample.csv', header=None,
skiprows=lambda x: x not in [0, 2])
print(df_none_skiprows)
# 0 1 2 3
# 0 11 12 13 14
# 1 31 32 33 34
header
があるファイルの場合、header
の行も考慮する必要があるので注意。
df_header_skiprows = pd.read_csv('data/src/sample_header.csv', skiprows=[1])
print(df_header_skiprows)
# a b c d
# 0 21 22 23 24
# 1 31 32 33 34
df_header_skiprows = pd.read_csv('data/src/sample_header.csv', skiprows=[0, 3])
print(df_header_skiprows)
# 11 12 13 14
# 0 21 22 23 24
なお、index
を指定していてもskiprows
を行名で指定することはできない。
引数skipfooter
ファイルの末尾をスキップする場合、引数skipfooter
を使う。スキップする行数を整数で指定する。
環境によっては以下のようなWarningが出るので、引数engine='python'
を指定する。
ParserWarning: Falling back to the 'python' engine because the 'c' engine does not support skipfooter; you can avoid this warning by specifying engine='python'.
df_none_skipfooter = pd.read_csv('data/src/sample.csv', header=None,
skipfooter=1, engine='python')
print(df_none_skipfooter)
# 0 1 2 3
# 0 11 12 13 14
# 1 21 22 23 24
引数nrows
最初の数行だけを読み込むこともできる。引数nrows
を使う。
大きいサイズのファイルのデータを少し確認する場合に便利。
df_none_nrows = pd.read_csv('data/src/sample.csv', header=None, nrows=2)
print(df_none_nrows)
# 0 1 2 3
# 0 11 12 13 14
# 1 21 22 23 24
型(dtype)を指定して読み込み
pandas.DataFrame
は列ごとに型dtype
が設定されており、astype()
メソッドで変換(キャスト)できる。文字列とobject
型との関係など詳細は以下の記事を参照。
read_csv()
では値から各列の型dtype
が自動的に選択されるが、場合によっては引数dtype
で明示的に指定する必要がある。
以下のファイルを例とする。
,a,b,c,d
ONE,1,"001",100,x
TWO,2,"020",,y
THREE,3,"300",300,z
0
で始まる数値の列は引用符で囲まれていてもいなくてもデフォルトでは文字列ではなく数値としてみなされて、先頭の0
は省略されてしまう。
df_default = pd.read_csv('data/src/sample_header_index_dtype.csv', index_col=0)
print(df_default)
# a b c d
# ONE 1 1 100.0 x
# TWO 2 20 NaN y
# THREE 3 300 300.0 z
print(df_default.dtypes)
# a int64
# b int64
# c float64
# d object
# dtype: object
print(df_default.applymap(type))
# a b c d
# ONE <class 'int'> <class 'int'> <class 'float'> <class 'str'>
# TWO <class 'int'> <class 'int'> <class 'float'> <class 'str'>
# THREE <class 'int'> <class 'int'> <class 'float'> <class 'str'>
先頭の0
を含んだ文字列として扱いたい場合は、read_csv()
の引数dtype
を指定する。
引数dtype
に任意のデータ型を指定すると、index_col
で指定した列も含むすべての列がその型に変換されて読み込まれる。例えばdtype=str
とすると、すべての列が文字列にキャストされる。ただし、この場合も欠損値はfloat
型。
df_str = pd.read_csv('data/src/sample_header_index_dtype.csv',
index_col=0, dtype=str)
print(df_str)
# a b c d
# ONE 1 001 100 x
# TWO 2 020 NaN y
# THREE 3 300 300 z
print(df_str.dtypes)
# a object
# b object
# c object
# d object
# dtype: object
print(df_str.applymap(type))
# a b c d
# ONE <class 'str'> <class 'str'> <class 'str'> <class 'str'>
# TWO <class 'str'> <class 'str'> <class 'float'> <class 'str'>
# THREE <class 'str'> <class 'str'> <class 'str'> <class 'str'>
dtype=object
としても同じ結果となる。
df_object = pd.read_csv('data/src/sample_header_index_dtype.csv',
index_col=0, dtype=object)
print(df_object)
# a b c d
# ONE 1 001 100 x
# TWO 2 020 NaN y
# THREE 3 300 300 z
print(df_object.dtypes)
# a object
# b object
# c object
# d object
# dtype: object
print(df_object.applymap(type))
# a b c d
# ONE <class 'str'> <class 'str'> <class 'str'> <class 'str'>
# TWO <class 'str'> <class 'str'> <class 'float'> <class 'str'>
# THREE <class 'str'> <class 'str'> <class 'str'> <class 'str'>
型変換(キャスト)できない型を引数dtype
に指定するとエラーになるので注意。この例ではindex_col
で指定した文字列のインデックス列を整数int
型に変換するところでエラーになっている。
# df_int = pd.read_csv('data/src/sample_header_index_dtype.csv',
# index_col=0, dtype=int)
# ValueError: invalid literal for int() with base 10: 'ONE'
読み込んだあとでpandas.DataFrame
の列の型を変換するにはastype()
メソッドに辞書形式で指定する。詳細は上述の関連記事を参照。
df_str_cast = df_str.astype({'a': int})
print(df_str_cast)
# a b c d
# ONE 1 001 100 x
# TWO 2 020 NaN y
# THREE 3 300 300 z
print(df_str_cast.dtypes)
# a int64
# b object
# c object
# d object
# dtype: object
read_csv()
での読み込み時に引数dtype
に辞書形式で列の型を指定することもできる。指定した列以外は自動で選ばれた型となる。
df_str_col = pd.read_csv('data/src/sample_header_index_dtype.csv',
index_col=0, dtype={'b': str, 'c': str})
print(df_str_col)
# a b c d
# ONE 1 001 100 x
# TWO 2 020 NaN y
# THREE 3 300 300 z
print(df_str_col.dtypes)
# a int64
# b object
# c object
# d object
# dtype: object
列名だけでなく列番号でも指定できる。インデックス列を指定している場合、インデックス列も含めた列番号で指定する必要があるので注意。
df_str_col_num = pd.read_csv('data/src/sample_header_index_dtype.csv',
index_col=0, dtype={2: str, 3: str})
print(df_str_col_num)
# a b c d
# ONE 1 001 100 x
# TWO 2 020 NaN y
# THREE 3 300 300 z
print(df_str_col_num.dtypes)
# a int64
# b object
# c object
# d object
# dtype: object
整数int
が2進数や16進数で保存されているといった場合などは、read_csv()
で文字列として読み込んだあとで所望の変換処理を行えばよい。以下の記事を参照。
- 関連記事: pandasで文字列と数値を相互変換、書式変更
欠損値NaNの扱い
デフォルトで欠損値とみなされる値
read_csv()
およびread_table()
ではデフォルトでいくつかの値が欠損値NaN
としてみなされるようになっている。
以下のように空文字列''
や文字列'NaN'
や'nan'
, null
など、考えられる値は概ねデフォルトで欠損値NaN
として扱われる。
By default the following values are interpreted as NaN: ‘’, ‘#N/A’, ‘#N/A N/A’, ‘#NA’, ‘-1.#IND’, ‘-1.#QNAN’, ‘-NaN’, ‘-nan’, ‘1.#IND’, ‘1.#QNAN’, ‘N/A’, ‘NA’, ‘NULL’, ‘NaN’, ‘n/a’, ‘nan’, ‘null’.
pandas.read_csv — pandas 0.23.0 documentation
以下のファイルを例として動作を確認する。
,a,b
ONE,,NaN
TWO,-,nan
THREE,null,N/A
特に引数を設定せずデフォルトで読み込んでisnull()
メソッドで確認すると、対象外の'-'
以外は欠損値NaN
として扱われていることが分かる。
df_nan = pd.read_csv('data/src/sample_header_index_nan.csv', index_col=0)
print(df_nan)
# a b
# ONE NaN NaN
# TWO - NaN
# THREE NaN NaN
print(df_nan.isnull())
# a b
# ONE True True
# TWO False True
# THREE True True
pandas.DataFrame
として読み込んだあとの欠損値の処理については以下の記事を参照。
欠損値として扱う値を追加: 引数na_values
デフォルトの値に追加して欠損値として扱う値を指定したい場合は引数na_values
を使う。
df_nan_set_na = pd.read_csv('data/src/sample_header_index_nan.csv',
index_col=0, na_values='-')
print(df_nan_set_na)
# a b
# ONE NaN NaN
# TWO NaN NaN
# THREE NaN NaN
print(df_nan_set_na.isnull())
# a b
# ONE True True
# TWO True True
# THREE True True
リストで指定すると複数の値を追加できる。
欠損値として扱う値を指定: 引数na_values, keep_default_na
引数keep_default_na
をFalse
としたうえで引数na_values
に値を指定すると、na_values
に指定した値のみが欠損値として扱われる。na_values
に指定しない限り、デフォルトの値は欠損値として扱われない。
df_nan_set_na_no_keep = pd.read_csv('data/src/sample_header_index_nan.csv',
index_col=0, na_values=['-', 'NaN', 'null'],
keep_default_na=False)
print(df_nan_set_na_no_keep)
# a b
# ONE NaN
# TWO NaN nan
# THREE NaN N/A
print(df_nan_set_na_no_keep.isnull())
# a b
# ONE False True
# TWO True False
# THREE True False
どの値も欠損値として扱わない: 引数na_filter
引数na_filter
をFalse
とすると、引数na_values
, keep_default_na
の指定によらずすべての値がそのままの文字列として読み込まれ、欠損値として扱われない。
df_nan_no_filter = pd.read_csv('data/src/sample_header_index_nan.csv',
index_col=0, na_filter=False)
print(df_nan_no_filter)
# a b
# ONE NaN
# TWO - nan
# THREE null N/A
print(df_nan_no_filter.isnull())
# a b
# ONE False False
# TWO False False
# THREE False False
エンコーディングの指定
エンコーディングは引数encoding
で指定する。
デフォルト(省略した場合)はutf-8
で、utf-8
ではないファイルに対しては文字化けするのではなくエラーUnicodeDecodeError
になる。
# df_sjis = pd.read_csv('data/src/sample_header_shift_jis.csv')
# UnicodeDecodeError: 'utf-8' codec can't decode byte 0x82 in position 0: invalid start byte
正しいエンコーディングを指定するとOK。
df_sjis = pd.read_csv('data/src/sample_header_shift_jis.csv',
encoding='shift_jis')
print(df_sjis)
# a b c d
# 0 あ 12 13 14
# 1 い 22 23 24
# 2 う 32 33 34
shift_jis
やcp932
のファイルを扱う場合は注意。
zipなどで圧縮されたファイルの読み込み
zipなどで圧縮されたcsvファイルをそのまま読み込むこともできる。
df_zip = pd.read_csv('data/src/sample_header.csv.zip')
print(df_zip)
# a b c d
# 0 11 12 13 14
# 1 21 22 23 24
# 2 31 32 33 34
拡張子が.gz
, .bz2
, .zip
, .xz
の場合、自動で検出して展開してくれる。拡張子が異なる場合、引数compression
に文字列'gz'
, 'bz2'
, 'zip'
, 'xz'
を明示的に指定する。
なお、対応しているのはcsvファイル単体が圧縮されている場合のみ。複数ファイルが圧縮されている場合はエラーになる。
zip
とxz
はバージョン0.18.1
からの対応。
Web上のファイルの読み込み
これまでの例はローカルのファイルを指定してきたが、第一引数にはURLを指定することも可能。Web上のファイルを直接読み込める。
ただし、多くの場合、引数を適宜指定しないと読み込めなかったり余計なデータが含まれてしまったりするので何度か試行する必要がある。特にサイズの大きいファイルの場合はローカルにダウンロードしてトライしたほうがいいかもしれない。
東京都の郵便番号データを例とする。
df = pd.read_csv('http://www.post.japanpost.jp/zipcode/dl/oogaki/zip/13tokyo.zip',
header=None, encoding='shift_jis')
print(df.shape)
# (3851, 15)
print(df.head())
# 0 1 2 3 4 5 6 7 8 \
# 0 13101 100 1000000 トウキヨウト チヨダク イカニケイサイガナイバアイ 東京都 千代田区 以下に掲載がない場合
# 1 13101 102 1020072 トウキヨウト チヨダク イイダバシ 東京都 千代田区 飯田橋
# 2 13101 102 1020082 トウキヨウト チヨダク イチバンチヨウ 東京都 千代田区 一番町
# 3 13101 101 1010032 トウキヨウト チヨダク イワモトチヨウ 東京都 千代田区 岩本町
# 4 13101 101 1010047 トウキヨウト チヨダク ウチカンダ 東京都 千代田区 内神田
# 9 10 11 12 13 14
# 0 0 0 0 0 0 0
# 1 0 0 1 0 0 0
# 2 0 0 0 0 0 0
# 3 0 0 1 0 0 0
# 4 0 0 1 0 0 0
print(df.tail())
# 0 1 2 3 4 5 6 \
# 3846 13401 10015 1001511 トウキヨウト ハチジヨウジマハチジヨウマチ ミツネ 東京都
# 3847 13402 10017 1001701 トウキヨウト アオガシマムラ アオガシマムライチエン 東京都
# 3848 13421 10021 1002100 トウキヨウト オガサワラムラ イカニケイサイガナイバアイ 東京都
# 3849 13421 10021 1002101 トウキヨウト オガサワラムラ チチジマ 東京都
# 3850 13421 10022 1002211 トウキヨウト オガサワラムラ ハハジマ 東京都
# 7 8 9 10 11 12 13 14
# 3846 八丈島八丈町 三根 0 0 0 0 0 0
# 3847 青ヶ島村 青ヶ島村一円 0 0 0 0 0 0
# 3848 小笠原村 以下に掲載がない場合 0 0 0 0 0 0
# 3849 小笠原村 父島 0 0 0 0 0 0
# 3850 小笠原村 母島 0 0 0 0 0 0
tsvの読み込み
はじめに書いた通り、tsvファイル(タブ区切り)を読みたいときはread_table()
を使えばよい。
以下のようなファイルの場合。
a b c d
ONE 11 12 13 14
TWO 21 22 23 24
THREE 31 32 33 34
引数などはread_csv()
と同じ。
df_tsv = pd.read_table('data/src/sample_header_index.tsv', index_col=0)
print(df_tsv)
# a b c d
# ONE 11 12 13 14
# TWO 21 22 23 24
# THREE 31 32 33 34
read_csv()
で区切り文字にタブ文字\t
を設定しても読める。
df_tsv_sep = pd.read_csv('data/src/sample_header_index.tsv', index_col=0, sep='\t')
print(df_tsv_sep)
# a b c d
# ONE 11 12 13 14
# TWO 21 22 23 24
# THREE 31 32 33 34