pandasでCSV/TSVファイル読み込み(read_csv, read_table)
pandasでCSVファイルやTSVファイルをDataFrame
として読み込むにはread_csv()
を使う。
- pandas.read_csv — pandas 2.0.3 documentation
- IO tools (text, CSV, HDF5, …) - CSV & text files — pandas 2.0.3 documentation
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)
日時情報を含むCSVファイルを時系列データとして読み込む方法については以下の記事を参照。
本記事のサンプルコードのpandasのバージョンは以下の通り。バージョンによって仕様が異なる可能性があるので注意。
import pandas as pd
print(pd.__version__)
# 2.0.3
read_csv()の基本的な使い方
read_csv()
の第一引数にCSVファイルのパスを指定するとDataFrame
として読み込まれる。
df = pd.read_csv('data/src/sample_header.csv')
print(df)
# a b c d
# 0 11 12 13 14
# 1 21 22 23 24
# 2 31 32 33 34
パスは絶対パスでも相対パスでもよい。カレントディレクトリの確認や変更については以下の記事を参照。
デフォルトでは、CSVファイルの一行目(ヘッダー)が列名columns
として扱われる。read_csv()
の引数によって、ヘッダーの扱いなどの様々な項目を設定できる。
以下、多くのユースケースで必要となると思われる主要な引数について説明する。本記事で扱っていない引数も数多くあるので、詳細は公式ドキュメントを参照されたい。
headerがないCSVの読み込み: 引数header, names
header(見出し行)がない以下のようなCSVファイルを読み込む。
11,12,13,14
21,22,23,24
31,32,33,34
デフォルトでは一行目がheaderとして認識され、列名columns
に割り当てられる。
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
とすると0始まりの連番が列名columns
になる。
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
にリストやタプルで指定する。
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, names
headerがある以下のようなCSVファイルを読み込む。
a,b,c,d
11,12,13,14
21,22,23,24
31,32,33,34
上述のように、デフォルトで一行目がheaderとして認識され、列名columns
に割り当てられる。
df = pd.read_csv('data/src/sample_header.csv')
print(df)
# a b c d
# 0 11 12 13 14
# 1 21 22 23 24
# 2 31 32 33 34
一行目とは別の任意の値を列名として設定するには、header=0
とした上で、引数names
にリストなどで指定する。header=0
がないと一行目がデータとして残ってしまうので注意。
df_names = pd.read_csv('data/src/sample_header.csv', names=['A', 'B', 'C', 'D'])
print(df_names)
# A B C D
# 0 a b c d
# 1 11 12 13 14
# 2 21 22 23 24
# 3 31 32 33 34
df_names_0 = pd.read_csv('data/src/sample_header.csv',
header=0, names=['A', 'B', 'C', 'D'])
print(df_names_0)
# A B C D
# 0 11 12 13 14
# 1 21 22 23 24
# 2 31 32 33 34
header=2
のようにheaderとして扱う行番号を0始まりで指定することもできる。指定した行より上の行は無視される。
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の読み込み: 引数index_col
headerとindex(見出し列)がある以下のようなCSVファイルを読み込む。
,a,b,c,d
ONE,11,12,13,14
TWO,21,22,23,24
THREE,31,32,33,34
デフォルトでは行名index
は0始まりの連番となる。一列目は特別扱いされない。
df = pd.read_csv('data/src/sample_header_index.csv')
print(df)
# 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.index)
# RangeIndex(start=0, stop=3, step=1)
引数index_col
にindex
として使いたい列の列番号を0始まりで指定できる。
df_index_col = pd.read_csv('data/src/sample_header_index.csv', index_col=0)
print(df_index_col)
# a b c d
# ONE 11 12 13 14
# TWO 21 22 23 24
# THREE 31 32 33 34
print(df_index_col.index)
# Index(['ONE', 'TWO', 'THREE'], dtype='object')
列を指定(選択)して読み込み: 引数usecols
特定の列だけを読み込むには、引数usecols
を使う。読み込む列番号または列名をリストで指定する。
df_usecols = pd.read_csv('data/src/sample_header.csv', usecols=[1, 3])
print(df_usecols)
# b d
# 0 12 14
# 1 22 24
# 2 32 34
df_usecols = pd.read_csv('data/src/sample_header.csv', usecols=['a', 'c'])
print(df_usecols)
# a c
# 0 11 13
# 1 21 23
# 2 31 33
ラムダ式などの呼び出し可能オブジェクトも指定可能。列名が渡され、真となる列のみが抽出される。特に列数が多いファイルから少数の列を除外して読み込みたいときは、読み込む列名や列番号を大量に指定するより楽。
df_usecols = pd.read_csv('data/src/sample_header.csv',
usecols=lambda x: x != 'b')
print(df_usecols)
# a c d
# 0 11 13 14
# 1 21 23 24
# 2 31 33 34
df_usecols = pd.read_csv('data/src/sample_header.csv',
usecols=lambda x: x not in ['a', 'c'])
print(df_usecols)
# b d
# 0 12 14
# 1 22 24
# 2 32 34
行をスキップ(除外)して読み込み
先頭のn行または行番号を指定してスキップ: 引数skiprows
特定の行をスキップ(除外)して読み込むには、引数skiprows
を使う。
整数を指定すると、ファイルの先頭n行をスキップして読み込む。
df = pd.read_csv('data/src/sample.csv', header=None)
print(df)
# 0 1 2 3
# 0 11 12 13 14
# 1 21 22 23 24
# 2 31 32 33 34
df_skiprows = pd.read_csv('data/src/sample.csv', header=None, skiprows=2)
print(df_skiprows)
# 0 1 2 3
# 0 31 32 33 34
スキップする行番号をリストで指定することもできる。usecols
とは違って、指定するのは読み込む行ではなくスキップする行。
df_skiprows = pd.read_csv('data/src/sample.csv', header=None, skiprows=[0, 2])
print(df_skiprows)
# 0 1 2 3
# 0 21 22 23 24
ラムダ式などの呼び出し可能オブジェクトも指定可能。行番号が渡され、真となる行をスキップする。特に行数が多いファイルから特定の行だけを読み込みたいときは、スキップする行番号を大量に指定するより楽。
df_skiprows = pd.read_csv('data/src/sample.csv', header=None,
skiprows=lambda x: x not in [0, 2])
print(df_skiprows)
# 0 1 2 3
# 0 11 12 13 14
# 1 31 32 33 34
headerがあるファイルの場合、headerの行が0行目として扱われるので注意。
df_skiprows = pd.read_csv('data/src/sample_header.csv', skiprows=2)
print(df_skiprows)
# 21 22 23 24
# 0 31 32 33 34
df_skiprows = pd.read_csv('data/src/sample_header.csv', skiprows=[1, 3])
print(df_skiprows)
# a b c d
# 0 21 22 23 24
なお、index_col
でindex
として扱う列を指定していてもskiprows
を行名で指定することはできない。
末尾のn行をスキップ: 引数skipfooter
ファイルの末尾をスキップするには、引数skipfooter
を使う。スキップする末尾の行数を整数で指定する。
df_skipfooter = pd.read_csv('data/src/sample.csv', header=None,
skipfooter=1, engine='python')
print(df_skipfooter)
# 0 1 2 3
# 0 11 12 13 14
# 1 21 22 23 24
環境によっては以下のような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'.
先頭のn行のみ読み込み: 引数nrows
引数nrows
を使うと、最初n行だけを読み込むことができる。大きいサイズのファイルのデータを少し確認する場合に便利。
df_nrows = pd.read_csv('data/src/sample.csv', header=None, nrows=2)
print(df_nrows)
# 0 1 2 3
# 0 11 12 13 14
# 1 21 22 23 24
headerがあるファイルの場合、headerの行はカウントに含まれない。
df_nrows = pd.read_csv('data/src/sample_header.csv', nrows=2)
print(df_nrows)
# a b c d
# 0 11 12 13 14
# 1 21 22 23 24
データ型(dtype)を指定して読み込み
pandas.DataFrame
は列ごとにデータ型dtype
が設定されている。文字列とobject
型との関係など詳細は以下の記事を参照。
read_csv()
では各列のデータ型が値から推測されて自動的に選ばれるが、引数dtype
で明示的に指定することもできる。
以下のファイルを例とする。
,a,b,c,d
ONE,1,"001",100,x
TWO,2,"020",,y
THREE,3,"300",300,z
例えば、0
で始まる数値の列は引用符で囲まれていてもいなくてもデフォルトでは数値とみなされ、先頭の0
は無視される。
df = pd.read_csv('data/src/sample_header_index_dtype.csv', index_col=0)
print(df)
# a b c d
# ONE 1 1 100.0 x
# TWO 2 20 NaN y
# THREE 3 300 300.0 z
print(df.dtypes)
# a int64
# b int64
# c float64
# d object
# dtype: object
先頭の0
を含む文字列として扱いたい場合は、read_csv()
の引数dtype
を指定する。
すべての列に同じデータ型dtypeを指定
引数dtype
に任意のデータ型を指定すると、index_col
で指定した列も含めてすべての列がその型に変換される。
指定した型に変換できない値があるとエラーになるので注意。
# pd.read_csv('data/src/sample_header_index_dtype.csv',
# index_col=0, dtype=float)
# ValueError: could not convert string to float: 'ONE'
dtype=str
とすると、すべての列が文字列に変換される。ただし、この場合も欠損値NaN
は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
を指定せずに読み込んだ後にastype()
でstr
にキャストした場合は欠損値も文字列'nan'
に変換される。
df = pd.read_csv('data/src/sample_header_index_dtype.csv', index_col=0)
print(df.astype(str))
# a b c d
# ONE 1 1 100.0 x
# TWO 2 20 nan y
# THREE 3 300 300.0 z
print(df.astype(str).applymap(type))
# a b c d
# ONE <class 'str'> <class 'str'> <class 'str'> <class 'str'>
# TWO <class 'str'> <class 'str'> <class 'str'> <class 'str'>
# THREE <class 'str'> <class 'str'> <class 'str'> <class 'str'>
列ごとにデータ型dtypeを指定
引数dtype
には辞書(dict
)で列の型を個別に指定することもできる。指定した列以外は自動で選ばれた型となる。
df_col = pd.read_csv('data/src/sample_header_index_dtype.csv',
index_col=0, dtype={'a': float, 'b': str})
print(df_col)
# a b c d
# ONE 1.0 001 100.0 x
# TWO 2.0 020 NaN y
# THREE 3.0 300 300.0 z
print(df_col.dtypes)
# a float64
# b object
# c float64
# d object
# dtype: object
辞書のキーは列番号でもよい。インデックス列を指定している場合、インデックス列も含めた列番号で指定する必要があるので注意。
df_col = pd.read_csv('data/src/sample_header_index_dtype.csv',
index_col=0, dtype={1: float, 2: str})
print(df_col)
# a b c d
# ONE 1.0 001 100.0 x
# TWO 2.0 020 NaN y
# THREE 3.0 300 300.0 z
print(df_col.dtypes)
# a float64
# b object
# c float64
# d object
# dtype: object
整数int
が2進数や16進数で保存されているといった場合などは、read_csv()
で文字列として読み込んだあとで所望の変換処理を行えばよい。以下の記事を参照。
- 関連記事: pandasで文字列と数値を相互変換、書式変更
欠損値NaNを含むCSVの読み込み
デフォルトで欠損値とみなされる値
read_csv()
ではデフォルトでいくつかの値が欠損値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”, “<NA>”, “N/A”, “NA”, “NULL”, “NaN”, “None”, “n/a”, “nan”, “null “. pandas.read_csv — pandas 2.0.3 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, keep_default_na
欠損値として扱う値を指定するには、引数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
引数keep_default_na
をFalse
とすると、上述のデフォルト値が欠損値として扱われなくなる。このとき引数na_values
を指定すると、na_values
に指定した値のみが欠損値として扱われる。
df_nan_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_no_keep)
# a b
# ONE NaN
# TWO NaN nan
# THREE NaN N/A
print(df_nan_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, encoding_errors
以下、Shift-JISでエンコードされたファイルを例とする。
エンコーディングは引数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 8: invalid start byte
正しいエンコーディングを指定する必要がある。shift_jis
やcp932
のファイルを扱う場合は注意。
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
引数encoding_errors
にエラー処理を指定できる。
デフォルトは'strict'
で、上述のようにエラーになる。'ignore'
や'replace'
などを指定可能。
df_ignore = pd.read_csv('data/src/sample_header_shift_jis.csv',
encoding_errors='ignore')
print(df_ignore)
# a b c d
# 0 NaN 12 13 14
# 1 NaN 22 23 24
# 2 NaN 32 33 34
df_replace = pd.read_csv('data/src/sample_header_shift_jis.csv',
encoding_errors='replace')
print(df_replace)
# a b c d
# 0 �� 12 13 14
# 1 �� 22 23 24
# 2 �� 32 33 34
df_backslash = pd.read_csv('data/src/sample_header_shift_jis.csv',
encoding_errors='backslashreplace')
print(df_backslash)
# a b c d
# 0 \x82\xa0 12 13 14
# 1 \x82\xa2 22 23 24
# 2 \x82\xa4 32 33 34
ZIPなどで圧縮されたファイルの読み込み
read_csv()
では、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
, .zst
, .tar
, .tar.gz
, .tar.xz
, .tar.bz2
の場合は、自動で検出して展開してくれる。拡張子が異なる場合は、引数compression
に文字列'zip'
(ピリオドは不要)などを明示的に指定する。
なお、対応しているのはCSVファイル単体が圧縮されている場合のみ。複数ファイルが圧縮されている場合はエラーになる。
Web上のファイルの読み込み
これまでの例はローカルのファイルを指定してきたが、read_csv()
の第一引数にはURLを指定することも可能。Web上のファイルを直接読み込める。ZIP圧縮されていてもよい。
GitHub上のCSVファイルを例とする。CSVファイル自体(Rawデータ)を示すURLでなければならないので注意。
df_web = pd.read_csv(
'https://raw.githubusercontent.com/nkmk/python-snippets/master/notebook/data/src/sample_header.csv'
)
print(df_web)
# a b c d
# 0 11 12 13 14
# 1 21 22 23 24
# 2 31 32 33 34
なお、多くの場合、引数を適宜指定しないと読み込めなかったり余計なデータが含まれてしまったりするので何度か試行する必要がある。特にサイズの大きいファイルの場合はローカルにダウンロードしてトライしたほうがいいかもしれない。
TSVファイルの読み込み: 引数sep
TSVファイル(タブ区切り)を読み込むには、read_csv()
の引数sep
にタブ文字\t
を指定する。
a b c d
ONE 11 12 13 14
TWO 21 22 23 24
THREE 31 32 33 34
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
read_table()
はデフォルトの区切り文字がタブ文字\t
となっている。引数などは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