- APIドキュメント
- サンプルコード
- 読み込むファイル名を指定 filepath_or_buffer
- 区切り文字の指定 sep, delimiter
- 空白文字を区切り文字に指定 delim_whitespace
- ヘッダーを指定する header
- 列(カラム)ごとの名称を定める names
- インデックスとして使う列(カラム)データを指定する index_col
- 読み込みたい列(カラム)を指定する usecols
- 1列だけのデータだったときにSeriesを返す squeeze
- 列番号の頭に文字を付け加える prefix
- 同じカラムラベルを区別する mangle_dupe_cols
- データ型を指定する dtype
- ファイルの読み込むエンジンを指定する engine
- 列ごとに行う処理を定める converters
- True,Falseとしてカウントすべき値を指定する true_values, false_valuees
- カンマ直後にあるスペースを省略する skipinitialspace
- 特定の行を読み飛ばす skiprows
- 末尾の何行かを読み飛ばす skipfooter
- 読み込む行数を指定する nrows
- メモリーの使用量を抑える low_memory
- ファイルアクセスを高速化する memory_map
- 欠損値として認識させる値を指定する na_values
- デフォルトで指定されている欠損値を読み込む設定を保持するか指定する keep_default_na
- 欠損値を検出するかどうか指定する na_filter
- 欠損値の処理にかかった時間を表示する verbose
- 空白の行を読み飛ばす skip_blank_lines
- 日付データとして処理するカラムを指定する parse_dates
- 日付データを読み込む速度を向上させる infer_datetime_format
- 日付データとして結合される前の列データを残す keep_date_col
- 日付データへの変換する処理を指定する date_parser
- 日/月のフォーマットを読み込む dayfrist
- イテレータを返す iterator
- 小分けにして処理をする chunksize
- 圧縮フォーマットを指定して読み込む compression
- 1000の位ごとにおかれる区切り文字を認識する thousands
- 小数点の値を指定する decimal
- 浮動小数を読み込むコンバータを指定する float_precision
- 行ごとの区切り文字を指定する lineterminator
- 引用を示すときに使う文字を指定する quotechar
- クオーテーションの中にある文字列の処理の仕方を指定する quoting
- クオーテーションとして指定した文字を文字列として認識する doublequote
- 特殊文字をエスケープさせる文字を指定する escapechar
- コメントアウトする文字列を指定する comment
- ファイルを読み込む文字コードを指定する encoding
- csvファイルの読み込み方を一括で指定する dialect
- MultiIndexを作成しようとする tupleize_cols
- サイズに合わない行が出てきた時の対処の仕方を指定する error_bad_lines
- 多すぎるデータを検出したときに警告メッセージを出すかどうか指定する warm_bad_lines
- まとめ
- 参考
本記事では引数の多いread_csv
関数とread_table
関数について解説します。全ての引数についての説明をします。関数を使用する際の辞書代わりにお使いください。
read_csv
とread_table
の違いは、区切り文字が','
であるか、'\t'
(タブ文字)であるかの違いしかなくそのほかは全く一緒になります。
以下ではread_csv
の場合について扱っていきますが、 そのままread_table
にも適用できます。
read_csv
関数のよく使うものだけをまとめた記事は以下のリンクから読めます。
Pandasのread_csv関数の使い方(簡易版) /features/pandas-readcsv-light.html
この記事では
- 全ての引数を含めたread_csv関数の使い方
について解説していきます。
APIドキュメント
まずはread_csv関数のAPIドキュメントからみていきます。引数の数が本当に膨大なのでかなり長くなります。
pandas.read_csv(filepath_or_buffer, sep=’, ‘, delimiter=None, header=’infer’, names=None, index_col=None, usecols=None, squeeze=False, prefix=None, mangle_dupe_cols=True, dtype=None, engine=None, converters=None, true_values=None, false_values=None, skipinitialspace=False, skiprows=None, nrows=None, na_values=None, keep_default_na=True, na_filter=True, verbose=False, skip_blank_lines=True, parse_dates=False, infer_datetime_format=False, keep_date_col=False, date_parser=None, dayfirst=False, iterator=False, chunksize=None, compression=’infer’, thousands=None, decimal=b’.’, lineterminator=None, quotechar=’”’, quoting=0, escapechar=None, comment=None, encoding=None, dialect=None, tupleize_cols=None, error_bad_lines=True, warn_bad_lines=True, skipfooter=0, doublequote=True, delim_whitespace=False, low_memory=True, memory_map=False, float_precision=None)
params:
パラメータ名 | 型 | 概要 |
---|---|---|
filepath_or_buffer |
パス名もしくはURL, read()関数が使われている オブジェクト |
読み込むファイルを指定します。 |
sep |
str | (省略可能)初期値 “,” 区切り文字を指定します。Noneにしてしまうと C エンジン(engine)で処理を行った場合、区切り文字を自動抽出することができません。Python エンジン(engine)なら可能です。 |
delimiter |
str | (省略可能)初期値 None sepと同じ役割を果たします。 |
delim_whitespace |
bool値 | (省略可能)初期値False ’ ‘や’\t’といった空白部分を区切り文字として使うかどうかを指定します。Trueにするとsep=”\s+”と同じ役割を果たします。Trueにしたとき delimiter 引数には何も渡してはいけません。 |
header |
int もしくは intのリスト |
(省略可能)初期値’infer’ 列(カラム)名としてどの行を使うかを指定し、それと同時にデータ部分の始まりの位置も指定します。リストで渡すとMultiIndexとしてデータを読み込みます。 |
names |
配列 | (省略可能)初期値None 列(カラム)名を指定します。ファイルにヘッダーが含まれているときはheader=Noneにする必要があります。 |
index_col |
intもしくはシーケンス もしくはFalse |
(省略可能)初期値False インデックスラベルとして使用する列(カラム)を指定します。シーケンスが渡されるとMultiIndexとなります。Falseにすると最初の列(カラム)をインデックスラベルとして使用しないようにできます。 |
usecols |
リストもしくは 呼び出し可能なもの |
(省略可能)初期値None 指定された一部の列(カラム)だけを読み込みます。指定された要素の順番は無視されて読み込まれます。 |
squeeze |
bool値 | (省略可能)初期値False Trueにするとデータが1列しかなかった場合Seriesを返すようにします。 |
prefix |
str | (省略可能)初期値None ヘッダーがなかったとき、列(カラム)ラベルの前につける文字列を指定します。’Y’のとき、ラベルは’Y0, Y1, Y2..’となります。 |
mangle_dupe_cols |
bool値 | (省略可能)初期値True 同じ名前の列(カラム)ラベルがあったときにそれぞれの名称を個別に見れるよう番号が付け加えられます。 |
dtype |
型名もしくは カラムの辞書->type |
(省略可能)初期値None データもしくは列(カラム)ごとの型を指定します。 |
engine |
‘c’または’python’ | (省略可能)初期値None データを読み込む際に使うエンジンを指定します。Cエンジンの方が高速で、Pythonエンジンの方がより柔軟に様々な場合に対処できます。 |
converters |
辞書 | (省略可能)初期値None 関数の辞書を指定します。特定の列に対して行う操作、処理を指定します。キーには番号でも列(カラム)名でも構いません。 |
true_values |
リスト | (省略可能)初期値None Trueとして認識する値を設定します。 |
false_values |
リスト | (省略可能)初期値None Falseとして認識する値を設定します。 |
skipinitialspace |
bool値 | (省略可能)初期値False Trueにすると区切り文字の直後にある空白を読み飛ばします。 |
skiprows |
リストもしくは番号 | (省略可能)初期値None 読み飛ばす行をリストで指定できます。番号だけのときはその番号までの行を全て読み飛ばします。 |
skipfooter |
int | (省略可能)初期値0 ファイルの最後からいくつの行を読み飛ばすかを指定します。 |
nrows |
int | (省略可能)初期値None 読み込む行数を指定します。 |
low_memory |
bool値 | (省略可能)初期値True engine=”C”のときのみ有効。Trueにするとメモリーの使用量を抑えます。 |
memory_map |
bool値 | (省略可能)初期値False filepathがfilepath_or_bufferに渡されると、ファイルオブジェクトをメモリ上で直接マッピングします。そこから直接データにアクセスします。Trueにするとファイルにアクセスするとき毎回フォルダを辿っていく必要がなくなるのでいくらかのパフォーマンス向上が見込めます。 |
na_values |
スカラー,str, リスト,辞書 |
(省略可能)初期値None 欠損値として認識する値を新たに追加します。辞書が渡されたら、キーで指定された列(カラム)にのみ適用されます。 |
keep_default_na |
bool値 | (省略可能)初期値True デフォルトで設定されている、欠損値として認識する値のリストを使うかどうかを指定します。keep_defult_na=Falseでna_values=Noneの場合、何もNaNに変換しないことになります。 |
na_filter |
bool値 | (省略可能)初期値True 欠損値がないかどうかを確かめる処理を行うかどうかを指定します。欠損値がないことがわかっているときはFalseにすると大規模なデータを読み込むときにパフォーマンスの向上が見込めます。 |
verbose |
bool値 | (省略可能)初期値False 欠損値の処理をするのにかかった時間などを表示します。 |
skip_blank_lines |
bool値 | (省略可能)初期値True Trueにすると何も記入されてない行があれば欠損値として処理はせず読み飛ばします。 |
parse_dates |
bool値もしくは intやnames,辞書,リスト のリスト |
(省略可能)初期値False 時刻データとして処理させたいものを指定します。Trueのときはインデックスラベルを変換しようと試みます。 |
infer_datetime_format |
bool値 | (省略可能)初期値False Trueにすると列(カラム)データ部分がdatetimeのフォーマットになっているかどうかを確かめることでparse_datesを列(カラム)データにまで適用します。 |
keep_date_col |
bool値 | (省略可能)初期値False Trueのときdatetime型に変換された列だけでなく変換する前の列も残すようになります。 |
date_parser |
関数 | (省略可能)初期値None datetime型に変換する前に行う処理を指定します。 |
dayfirst |
bool値 | (省略可能)初期値False 月/日のフォーマットから日/月に変更します。 |
iterator |
bool値 | (省略可能)初期値False TrueにするとtextFileReaderオブジェクトを返します。繰り返し処理などのイテレーションに使われます。 |
chunksize |
int | (省略可能)初期値Noneiterator=True のときと同様、textFileReaderオブジェクトを返します。一回のイテレーターに渡すデータ数を指定します。 |
compression |
‘infer’,’gzip’, ‘bz2’,’zip’,’xz’,None のいずれか |
(省略可能)初期値None 解凍する圧縮ファイルの種類を指定します。デフォルトの’infer’ではいずれかの文字列がファイル名に含まれていればその形式にしたがって解凍しますが、個別に指定すると指定された形式で解凍を試みます。 |
thousands |
str | (省略可能)初期値None 1000ごとに区切りにいれられる文字を指定する。1,000だったら’,’を指定すればよい。 |
decimal |
str | (省略可能)初期値’.’ 小数点に使われる文字を指定します。ヨーロッパのデータなら’,’を使います。 |
float_precision |
str | (省略可能)初期値None Cエンジンがどのコンバーターを使えば良いのかを指定します。Noneなら一般的なものが使われます。highのときは高精度のコンバーターを使用し、round-tripのときはround-tripコンバーターを使用します。 |
lineterminator |
長さ1のstr | (省略可能)初期値None Cエンジンのときのみ有効。行ごとの区切り文字を指定します。 |
quotechar |
長さ1のstr | (省略可能)初期値’”‘ 引用を示すときに使われる文字を指定します。 |
quoting |
intもしくは csv.QUOTE_*のインスタンス |
(省略可能)初期値0 クォーテーションの中にある文字列をどう処理するかを指定します。 |
doublequote |
bool値 | (省略可能)初期値True quotecharが指定され、quotingがQUOTE_NONEでないとき、クオーテーションが有効になっているフィールド内でquotecharで指定されている文字が2つ続いたとき、クオーテーションではなく1つ文字を示すものとして認識します。 |
escapechar |
長さ1のstr | (省略可能)初期値None quoting=QUOTE_NONEのとき、クォーテーション内で区切り文字を無効にします。 |
comment |
str | (省略可能)初期値None コメントとして認識するための文字を設定します。行頭でその文字があったらその行を丸ごと読み飛ばします。 |
encoding |
str | (省略可能)初期値None ファイルを読み込む際に使用する文字コードを指定します。 |
dialect |
strもしくは csv.Dialectの インスタンス |
(省略可能)初期値None 区切り文字、引用に関する処理の決まりをまとめて指定します。delimiter, doublequote, escapechar, skipinitialspace, quotechar, quoting引数の値がこれによって全て上書きされます。 |
tupleize_cols |
bool値 | 非推奨 (省略可能)初期値False 列(カラム)名の上にあるラベルをタプルにしたリストを指定します。これを使ってMultiIndexを作成します。(非推奨となっており、これからはデフォルトでMultiIndexに変換できないか試みるようになるそうです) |
error_bad_lines |
bool値 | (省略可能)初期値True Trueにすると他の列よりも多くの区切り文字を検出するとエラーを返してDataFrameを返しません。Falseにするとそれらのうまくマッチしない行は丸ごと読み飛ばされた状態でファイルが読み込まれます。 |
warm_bad_lines |
bool値 | (省略可能)初期値True error_bad_lines=Falseでwarm_bad_lines=Trueにすると、各々のbad_lineに対して警告(warning)が表示されます。 |
returns:
csvファイルの中身を読み込んだDataFrameまたはテキストパーサーが返されます。
計49個もの引数が存在してました。ものすごい数ですね。これらを駆使することでcsvファイルの読み取り方を詳細に設定することができます。
サンプルコード
それでは1つずつ使っていきましょう。その都度場合に合わせたcsvファイルを使っていきます。
読み込むファイル名を指定 filepath_or_buffer
読み込むファイルを指定します。
class,grade,name
A,1,Satou
B,1,Hashimoto
B,3,Takahashi
A,2,Aikawa
これをsample1.csvで保存します(上のリンクをクリックするとダウンロード可能です)。
In [1]: import pandas as pd
In [2]: df = pd.read_csv("sample1.csv")
In [3]: df
Out[3]:
class grade name
0 A 1 Satou
1 B 1 Hashimoto
2 B 3 Takahashi
3 A 2 Aikawa
区切り文字の指定 sep, delimiter
sep
とdelimiter
で区切り文字を指定できます。
id;class;grade;name
0;A;1;Satou
1;B;1;Hashimoto
2;B;3;Takahashi
3;A;2;Aikawa
これをsample2.csvで保存します。
In [9]: df = pd.read_csv("sample2.csv", sep=";")
In [10]: df
Out[10]:
id class grade name
0 0 A 1 Satou
1 1 B 1 Hashimoto
2 2 B 3 Takahashi
3 3 A 2 Aikawa
In [11]: df = pd.read_csv("sample2.csv", delimiter=";")
In [12]: df
Out[12]:
id class grade name
0 0 A 1 Satou
1 1 B 1 Hashimoto
2 2 B 3 Takahashi
3 3 A 2 Aikawa
空白文字を区切り文字に指定 delim_whitespace
空白文字を区切り文字にしたいときはdelim_whitespace
を使います。これをTrue
にすれば空白文字が区切り文字となります。
delimiter
やsep
に他の文字が指定されているとエラーになるので注意してください。(デフォルトの状態にしておけば問題ありません。)
id class grade name
0 A 1 Satou
1 B 1 Hashimoto
2 B 3 Takahashi
3 A 2 Aikawa
これをsample3.csvで保存します。
In [13]: df = pd.read_csv("sample3.csv", delim_whitespace=True)
In [14]: df
Out[14]:
id class grade name
0 0 A 1 Satou
1 1 B 1 Hashimoto
2 2 B 3 Takahashi
3 3 A 2 Aikawa
ヘッダーを指定する header
header
で列(カラム)名となる行を指定します。該当する行がないときはheader=None
にしておきましょう。
A,1,Satou
B,1,Hashimoto
B,3,Takahashi
A,2,Aikawa
これをsample4.csvで保存します。
In [16]: df = pd.read_csv("sample4.csv", header=None)
In [17]: df
Out[17]:
0 1 2
0 A 1 Satou
1 B 1 Hashimoto
2 B 3 Takahashi
3 A 2 Aikawa
次はヘッダーの位置が少しずれている場合を見てみます。
# this is header
class,grade,name
A,1,Satou
B,1,Hashimoto
B,3,Takahashi
A,2,Aikawa
このようなsample5.csvを使います。1行目にコメントがあるのでヘッダーの部分が0行目ではなく1行目に来ていることがわかります。header=1
とすることでこの形式に対応することができます。
In [18]: df = pd.read_csv("sample5.csv", header=1)
In [19]: df
Out[19]:
class grade name
0 A 1 Satou
1 B 1 Hashimoto
2 B 3 Takahashi
3 A 2 Aikawa
以下のようなカラム名がMultiIndexに相当する場合について考えてみましょう。
personal_data,personal_data,personal_data,score,score
class,grade,name,math,english
A,1,Satou,80,31
B,1,Hashimoto,29,28
B,3,Takahashi,65,76
A,2,Aikawa,88,92
これをsample6.csvで保存します。header=[0,1]
とリストで指定すれば問題ありません。
In [20]: df = pd.read_csv("sample6.csv",header=[0,1])
In [21]: df
Out[21]:
personal_data score
class grade name math english
0 A 1 Satou 80 31
1 B 1 Hashimoto 29 28
2 B 3 Takahashi 65 76
3 A 2 Aikawa 88 92
列(カラム)ごとの名称を定める names
先ほどのsample4.csvのデータを使います。
A,1,Satou
B,1,Hashimoto
B,3,Takahashi
A,2,Aikawa
names
を使って列(カラム)ごとに名称を定めましょう。
In [22]: df = pd.read_csv("sample4.csv",names=["class","grade","name"])
In [23]: df
Out[23]:
class grade name
0 A 1 Satou
1 B 1 Hashimoto
2 B 3 Takahashi
3 A 2 Aikawa
インデックスとして使う列(カラム)データを指定する index_col
id,class,grade,name
2,A,1,Satou
9,B,1,Hashimoto
19,B,3,Takahashi
25,A,2,Aikawa
となるsample7.csvのデータを使います。
index_col="id"
とすることで"id"
の列(カラム)データを使ってインデックスを設定します。番号で指定することも可能です。
In [24]: df = pd.read_csv("sample7.csv", index_col="id")
In [25]: df
Out[25]:
class grade name
id
2 A 1 Satou
9 B 1 Hashimoto
19 B 3 Takahashi
25 A 2 Aikawa
In [26]: df = pd.read_csv("sample7.csv", index_col=0)
In [27]: df
Out[27]:
class grade name
id
2 A 1 Satou
9 B 1 Hashimoto
19 B 3 Takahashi
25 A 2 Aikawa
読み込みたい列(カラム)を指定する usecols
usecols
を使って一部の列(カラム)だけを抜き出しましょう。再びsample1.csvのデータを使います。
class,grade,name
A,1,Satou
B,1,Hashimoto
B,3,Takahashi
A,2,Aikawa
In [28]: df = pd.read_csv("sample1.csv",usecols=["class"])
In [29]: df
Out[29]:
class
0 A
1 B
2 B
3 A
In [30]: df = pd.read_csv("sample1.csv", usecols=["grade","name"])
In [31]: df
Out[31]:
grade name
0 1 Satou
1 1 Hashimoto
2 3 Takahashi
3 2 Aikawa
また、ラムダ式などを使った呼び出し方もあります。
In [37]: df = pd.read_csv("sample1.csv", usecols = lambda x: x.upper() in ["NAME", "CLASS"])
In [38]: df
Out[38]:
class name
0 A Satou
1 B Hashimoto
2 B Takahashi
3 A Aikawa
1列だけのデータだったときにSeriesを返す squeeze
squeeze=True
にすると読み込んだデータが1列だけのデータだったときにDataFrame
ではなくSeries
として返すようになります。先ほどのusecols
と組み合わせて使ってみます。
In [32]: df = pd.read_csv("sample1.csv", usecols=["name"],squeeze=True)
In [33]: df
Out[33]:
0 Satou
1 Hashimoto
2 Takahashi
3 Aikawa
Name: name, dtype: object
In [34]: type(df)
Out[34]: pandas.core.series.Series
In [35]: df = pd.read_csv("sample1.csv",usecols=["name"]) # squeezeを指定しないとDataFrameになる
In [36]: type(df)
Out[36]: pandas.core.frame.DataFrame
列番号の頭に文字を付け加える prefix
先ほどのsample4.csvのデータを使います。
A,1,Satou
B,1,Hashimoto
B,3,Takahashi
A,2,Aikawa
このようなヘッダーのないcsvファイルは先ほどのheaderの解説でheader=None
にしてヘッダーを読み込まない設定にする必要があるということを扱いました。
この状態で読み込むとカラムのラベルが0,1,2....
と番号だけになってしまいます。
番号だけではなくて頭に文字列を付け加えてどんなデータのカラムなのかはっきりさせたいといった場合にprefix
引数は役立ちます。
prefix=<追加したい文字列>
で使うことができます。
In [14]: df = pd.read_csv("sample4.csv", header=None, prefix="classA_")
In [15]: df
Out[15]:
classA_0 classA_1 classA_2
0 A 1 Satou
1 B 1 Hashimoto
2 B 3 Takahashi
3 A 2 Aikawa
このような感じで使うことが可能です。
同じカラムラベルを区別する mangle_dupe_cols
以下のようなファイルsample9.csvを使って見ていきます。
class,grade,name,name
A,1,Satou,Takeru
B,1,Hashimoto,Yohko
B,3,Takahashi,Masashi
A,2,Aikawa,Haruka
ヘッダーにname
が2回使われています。この2つのname
を区別するためにmangle_dupe_cols
引数を使います。
この形式にはmangle_dupe_cols=True
またはmangle_dupe_cols=False
とすることで対処できます。
True
にすれば同じ名前のラベルがあったらそれらを区別できるように番号をラベル名の後ろにつけます。False
にすると列データがが他の同じラベルの列データに上書きされます。
デフォルトでTrue
になっているので、上書きして欲しいときにここをFalse
にすれば良いということになります。
In [3]: df = pd.read_csv("sample8.csv") # 何もオプションをつけないと同じラベルは区別される
In [4]: df
Out[4]:
class grade name name.1
0 A 1 Satou Takeru
1 B 1 Hashimoto NaN
2 B 3 Takahashi Satoru
3 A 2 Aikawa Yohko
次にmangle_dupe_cols=False
にして実行しようとしたらエラーが返って来てしまいました。
予想としては
df = pd.read_csv("sample8.csv", mangle_dupe_cols=False)
で読み込んでdf
を表示させると、
class grade name name
0 A 1 Takeru Takeru
1 B 1 NaN NaN
2 B 3 Satoru Satoru
3 A 2 Yohko Yohko
となり、左側のname
の値が全て右側のname
の値によって上書きされているということだったのですが、残念ながら手元の環境では実現できませんでした。
データ型を指定する dtype
次は読み込む際のデータ型を指定します。
この引数はengine='python'
のときだと無効になるため、engine='c'
(デフォルト)にしておく必要があります(engine
引数については次の項で解説します)。
あらかじめ型を指定しておくことで読み込みが早くなります。
データには以下のsample9.csvを使います。
class,grade,name,height
A,1,Satou,171.1
B,1,Hashimoto,155.3
B,3,Takahashi,180.4
A,2,Aikawa,160.8
In [2]: import numpy as np # データ型を明記するためにNumPyをインポートしておく
In [3]: df = pd.read_csv("sample9.csv",engine='c',dtype={'class':str,'grade':np.int32,'name':str,'height':np.float32})
In [4]: df
Out[4]:
class grade name height
0 A 1 Satou 171.100006
1 B 1 Hashimoto 155.300003
2 B 3 Takahashi 180.399994
3 A 2 Aikawa 160.800003
このような感じで使うことができます。
ファイルの読み込むエンジンを指定する engine
engine
でCのように読み込むかPythonのように読み込むかを指定することができます。デフォルトはc
になっており、こちらの方がより早くファイルを読み込むことができますが、Python
の方が動的に型を読み込んで行ってくれるので柔軟にファイルを読み込んでくれます。
ここではsample1.csvのデータを使います。
class,grade,name
A,1,Satou
B,1,Hashimoto
B,3,Takahashi
A,2,Aikawa
In [15]: df_c = pd.read_csv("sample1.csv", engine="c")
In [16]: df_c
Out[16]:
class grade name
0 A 1 Satou
1 B 1 Hashimoto
2 B 3 Takahashi
3 A 2 Aikawa
In [18]: df_python = pd.read_csv("sample1.csv", engine="python")
In [19]: df_python
Out[19]:
class grade name
0 A 1 Satou
1 B 1 Hashimoto
2 B 3 Takahashi
3 A 2 Aikawa
読み込み速度に違いが出るか、検証してみましょう。
In [21]: %timeit pd.read_csv("sample1.csv", engine="c")
3.96 ms ± 97.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [22]: %timeit pd.read_csv("sample1.csv", engine="python")
5.09 ms ± 211 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
4msと5msとで、はっきりとした差が出たことがわかりました。
列ごとに行う処理を定める converters
データを読み込むついでに簡単な処理をしたいときにconverters
で各列で行う処理を指定します。
ここではsample9.csvのデータを使います。
class,grade,name,height
A,1,Satou,171.1
B,1,Hashimoto,155.3
B,3,Takahashi,180.4
A,2,Aikawa,160.8
例えば、class
の名前を全部小文字にして、身長height
を2倍に変換しましょう。
In [39]: def func_1(x):
...: x = float(x)
...: return x*2
...:
In [40]: df = pd.read_csv("sample9.csv",converters={"class":lambda x : x.lower()
...: , "height":func_1})
In [41]: df
Out[41]:
class grade name height
0 a 1 Satou 342.2
1 b 1 Hashimoto 310.6
2 b 3 Takahashi 360.8
3 a 2 Aikawa 321.6
データ型を変換する用途もありますが、dtype
を使えば問題ないのでconverters
は簡単な前処理を指定できる引数という位置づけが適当でしょう。
True,Falseとしてカウントすべき値を指定する true_values, false_valuees
以下のようなアンケート結果を使ってみます。
name,q_1,q_2,q_3
Satou,Yes,No,No
Hashimoto,Yes,Yes,No
Takahashi,No,No,No
Aikawa,Yes,Yes,No
これをsample11.csvの名前で保存します。このアンケート結果のYes
をTrue
に、No
をFalse
に変換します。
In [42]: df = pd.read_csv("sample11.csv", true_values=["Yes"],false_values=["No"])
In [43]: df
Out[43]:
name q_1 q_2 q_3
0 Satou True False False
1 Hashimoto True True False
2 Takahashi False False False
3 Aikawa True True False
カンマ直後にあるスペースを省略する skipinitialspace
以下のようなデータsample12.csvを用意します。
class, grade, name
A, 1, Satou
B, 1, Hashimoto
B, 3, Takahashi
A, 2, Aikawa
このように、カンマなどの区切り文字のあとにスペースがあるデータについて考えます。これらのスペースをまとめて削除するためにはskipinitialspace=True
にすればよいです。
ただし、データ部分で2つ以上スペースが存在する場合はうまく機能しないことがあるので注意してください。
In [54]: df = pd.read_csv("sample12.csv",skipinitialspace=True)
In [58]: df
Out[58]:
class grade name
0 A 1 Satou
1 B 1 Hashimoto
2 B 3 Takahashi
3 A 2 Aikawa
In [59]: df.iloc[1,2]
Out[59]: 'Hashimoto'
In [60]: df.columns # スペースがなくなった状態になっている。
Out[60]: Index(['class', 'grade', 'name'], dtype='object')
In [61]: df_2 = pd.read_csv("sample12.csv") # skipinitialspace=Trueにしないと
In [62]: df_2.columns # スペースが削除されずに読み込まれる
Out[62]: Index([' class', ' grade', ' name'], dtype='object')
特定の行を読み飛ばす skiprows
以下のようなデータsample13.csvを用意します。
# ここから
class,grade,name
# ここまでがヘッダー
A,1,Satou
B,1,Hashimoto
B,3,Takahashi
A,2,Aikawa
このようにコメントが入っている行を読み飛ばしたい時はskiprows
を使うとよいです。
In [63]: df = pd.read_csv("sample13.csv", skiprows=[0,2])
In [64]: df
Out[64]:
class grade name
0 A 1 Satou
1 B 1 Hashimoto
2 B 3 Takahashi
3 A 2 Aikawa
末尾の何行かを読み飛ばす skipfooter
以下のようなデータsample14.csvを用意します。
class,grade,name
A,1,Satou
B,1,Hashimoto
B,3,Takahashi
A,2,Aikawa
ここの行と
ここの行を読み飛ばしたい
このようなデータの末尾にいらないものが入っているときにskipfooter
を使って末尾から何行分読み飛ばすかを指定します。
デフォルトのengine="c"
のときはこのオプションは無効なので注意してください。
engine="python"
でやりましょう。
In [65]: df = pd.read_csv("sample14.csv", engine="python", skipfooter=2) # 2行分
...: 読み飛ばす。 engineはpythonで
In [66]: df
Out[66]:
class grade name
0 A 1 Satou
1 B 1 Hashimoto
2 B 3 Takahashi
3 A 2 Aikawa
読み込む行数を指定する nrows
大規模なデータのうち一部分だけ使いたいときに便利なのがnrows
です。ここでもsample1.csvのデータを使います。
class,grade,name
A,1,Satou
B,1,Hashimoto
B,3,Takahashi
A,2,Aikawa
これの2行分だけデータを読み込んでみましょう。
In [69]: df = pd.read_csv("sample1.csv", nrows=2) # 上から2行だけ読み込む
In [70]: df
Out[70]:
class grade name
0 A 1 Satou
1 B 1 Hashimoto
メモリーの使用量を抑える low_memory
例えば1つの整数の列データの中に文字列といった他の型が紛れ込んでいないことがわかっているときはlow_memory=False
にすることによってpandasが一旦全部のファイルを読み込んで型を推測する必要がなくなります。
これと同じことはdtype
を指定することによってできます。
sample1.csvのデータを使います。
class,grade,name
A,1,Satou
B,1,Hashimoto
B,3,Takahashi
A,2,Aikawa
実行してみます。内部処理の問題なので、表面上の違いは一切出て来ません。
In [74]: df = pd.read_csv("sample1.csv",low_memory=True) # こちらがデフォルトの設定
In [75]: df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4 entries, 0 to 3
Data columns (total 3 columns):
class 4 non-null object
grade 4 non-null int64
name 4 non-null object
dtypes: int64(1), object(2)
memory usage: 176.0+ bytes
In [76]: df_2 = pd.read_csv("sample1.csv",low_memory=False)
In [77]: df_2.info() # 読み込んだ後のメモリー使用量自体は変わらない
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4 entries, 0 to 3
Data columns (total 3 columns):
class 4 non-null object
grade 4 non-null int64
name 4 non-null object
dtypes: int64(1), object(2)
memory usage: 176.0+ bytes
ファイルアクセスを高速化する memory_map
指定されたファイルへのアクセスをする際、一旦メモリ上に直接ファイルをマッピングしてしまいます。ファイルへアクセスするときに直接アクセスできるため、フォルダをたどる必要がなく、いくらかのパフォーマンス向上が見込めます。
memory_map=True
にすると使えます。デフォルトの値はFalse
。
In [78]: df = pd.read_csv("sample1.csv", memory_map=True)
In [79]: df
Out[79]:
class grade name
0 A 1 Satou
1 B 1 Hashimoto
2 B 3 Takahashi
3 A 2 Aikawa
欠損値として認識させる値を指定する na_values
sample15.csvのデータを使います。
class,grade,name
A,1,missing
B,0,Hashimoto
no_value,3,Takahashi
,2,
値がないことを示す部分がいくつか見受けられるのがわかると思います。no_value, 0, missing
の3つの値を欠損値として読み込ませましょう。
na_values=["no_value", 0, "missing"]
で指定できます。
In [82]: df = pd.read_csv("sample15.csv", na_values=["no_value", 0, "missing"])
In [83]: df
Out[83]:
class grade name
0 A 1.0 NaN
1 B NaN Hashimoto
2 NaN 3.0 Takahashi
3 NaN 2.0 NaN
デフォルトで指定されている欠損値を読み込む設定を保持するか指定する keep_default_na
Pandasはデータを読み込む際、いくつかのパターンを検知するとそれをNaN
値として処理する設定が存在します。
この設定を保持して読み込むか、保持しないかをkeep_default_na
で指定することが可能です。先ほどのna_values
とは切り離して考えるとわかりやすく、na_values
ではあくまで追加の設定を行うだけでデフォルトの設定をいじれるわけではありません。
一方、keep_default_na
は追加の設定は行えませんが、デフォルトの設定を適用させるかどうかを指定することができます。
先ほどと同じデータを使ってみます。
class,grade,name
A,1,missing
B,0,Hashimoto
no_value,3,Takahashi
,2,
In [84]: df = pd.read_csv("sample15.csv", keep_default_na=False) # keep_default_naだけFalseにすると何もNaN値として読み込まない
In [85]: df
Out[85]:
class grade name
0 A 1 missing
1 B 0 Hashimoto
2 no_value 3 Takahashi
3 2
In [86]: df_2 = pd.read_csv("sample15.csv", keep_default_na=False,na_values=["no_value", 0, "missing"]) # 追加で設定した値だけNaN値として読み込まれる
In [87]: df_2
Out[87]:
class grade name
0 A 1.0 NaN
1 B NaN Hashimoto
2 NaN 3.0 Takahashi
3 2.0
In [88]: df_3 = pd.read_csv("sample15.csv", keep_default_na=True,na_values=["no_value", 0, "missing"]) # デフォルトの設定も追加の設定もて適用される
In [89]: df_3
Out[89]:
class grade name
0 A 1.0 NaN
1 B NaN Hashimoto
2 NaN 3.0 Takahashi
3 NaN 2.0 NaN
欠損値を検出するかどうか指定する na_filter
na_filter=False
にすると欠損値かどうかを判定するプロセスを省いてデータを読み込みます。
以下のsample15.csvのデータを使います。
class,grade,name
A,1,missing
B,0,Hashimoto
no_value,3,Takahashi
,2,
In [90]: df = pd.read_csv("sample15.csv",na_values=["no_value",0,"missing"]) # 欠損値にあたる場所は全てNaNになる
In [91]: df
Out[91]:
class grade name
0 A 1.0 NaN
1 B NaN Hashimoto
2 NaN 3.0 Takahashi
3 NaN 2.0 NaN
In [92]: df_2 = pd.read_csv("sample15.csv", na_values=["na_value",0,"missing"],na_filter=False) # na_filter=Falseにするとそのままデータを読み込む
In [93]: df_2
Out[93]:
class grade name
0 A 1 missing
1 B 0 Hashimoto
2 no_value 3 Takahashi
3 2
欠損値の処理にかかった時間を表示する verbose
欠損値処理の時間などを表示するにはverbose=True
にすればよいです。以下のsample15.csvのデータを使います。
class,grade,name
A,1,missing
B,0,Hashimoto
no_value,3,Takahashi
,2,
In [94]: df = pd.read_csv("sample15.csv",na_values=["no_value",0,"missing"], verbose=True)
Tokenization took: 0.01 ms
Type conversion took: 1.61 ms
Parser memory cleanup took: 0.01 ms
空白の行を読み飛ばす skip_blank_lines
sample16.csvのデータを使います。
class,grade,name
A,1,Satou
B,1,Hashimoto
B,3,Takahashi
A,2,Aikawa
空白の行がいくつかあるのでそこをskip_blank_lines=True
にして読み飛ばします。
In [96]: df = pd.read_csv("sample16.csv",skip_blank_lines=True) # skip_blank_lines=Trueにして読み込み
In [97]: df
Out[97]:
class grade name
0 A 1 Satou
1 B 1 Hashimoto
2 B 3 Takahashi
3 A 2 Aikawa
日付データとして処理するカラムを指定する parse_dates
Pandasはファイルを読み込むときに自動的に日付データを検知することはしません。なので、手動で日付データとして読み込ませたいデータを指定する必要があります。parse_date
にリスト形式でカラムを指定することで、指定されたカラムの列データは全て時刻データとして扱われます。
以下のようなデータsample17.csvを使います。
id,class,grade,name,birth_date
001,A,1,Satou,1999/09/21
003,B,1,Hashimoto,2000/02/15
015,B,3,Takahashi,1997/04/05
102,A,2,Aikawa,1998/11/28
112,B,1,Sasaki,1999/10/30
ここのbirth_date
というデータを日付データとして読み込ませます。リスト形式で指定する必要があることに注意してください。
In [98]: df = pd.read_csv("sample17.csv", parse_dates=["birth_date"])
In [99]: df
Out[99]:
id class grade name birth_date
0 1 A 1 Satou 1999-09-21
1 3 B 1 Hashimoto 2000-02-15
2 15 B 3 Takahashi 1997-04-05
3 102 A 2 Aikawa 1998-11-28
4 112 B 1 Sasaki 1999-10-30
In [101]: df.dtypes # datetime型として読み込まれてるか確認
Out[101]:
id int64
class object
grade int64
name object
birth_date datetime64[ns]
dtype: object
また、複数列にまたがる日付データをまとめて読み込むこともできます。このときはparse_dates=[["birth_y","birth_m","birth_d"]]
のようにリストの中にリストを入れ込む形式で指定します。
id,class,grade,name,birth_y,birth_m,birth_d
001,A,1,Satou,1999,09,21
003,B,1,Hashimoto,2000,02,15
015,B,3,Takahashi,1997,04,05
102,A,2,Aikawa,1998,11,28
112,B,1,Sasaki,1999,10,30
これをsample18.csvで保存して読み込ませます。
In [104]: df_2 = pd.read_csv("sample18.csv",parse_dates=[["birth_y","birth_m","birth_d"]])
In [105]: df_2
Out[105]:
birth_y_birth_m_birth_d id class grade name
0 1999-09-21 1 A 1 Satou
1 2000-02-15 3 B 1 Hashimoto
2 1997-04-05 15 B 3 Takahashi
3 1998-11-28 102 A 2 Aikawa
4 1999-10-30 112 B 1 Sasaki
カラム名が汚くなりましたね。その場合はparse_dates={'birth_date':["birth_y","birth_m","birth_d"]}
のように辞書でキーを新しいカラム名にすれば対処できます。
In [106]: df_3 = pd.read_csv("sample18.csv",parse_dates={'birth_date':["birth_y","birth_m","birth_d"]})
In [107]: df_3
Out[107]:
birth_date id class grade name
0 1999-09-21 1 A 1 Satou
1 2000-02-15 3 B 1 Hashimoto
2 1997-04-05 15 B 3 Takahashi
3 1998-11-28 102 A 2 Aikawa
4 1999-10-30 112 B 1 Sasaki
parse_dates=True
にするとインデックスをdatetime型に変換しようとします。
In [108]: df_4 = pd.read_csv("sample17.csv", parse_dates=True, index_col="birth_date") # インデックスに指定された"birth_date"列がdatetime型に変換される
In [109]: df_4
Out[109]:
id class grade name
birth_date
1999-09-21 1 A 1 Satou
2000-02-15 3 B 1 Hashimoto
1997-04-05 15 B 3 Takahashi
1998-11-28 102 A 2 Aikawa
1999-10-30 112 B 1 Sasaki
日付データを読み込む速度を向上させる infer_datetime_format
先ほどのparse_dates
で何かしらのカラムが指定されている状態でinfer_datetime_format=True
になっていると、日付データのフォーマットの推測を試みることで読み込み速度を向上させます。
以下のデータsample17.csvを使います。
id,class,grade,name,birth_date
001,A,1,Satou,1999/09/21
003,B,1,Hashimoto,2000/02/15
015,B,3,Takahashi,1997/04/05
102,A,2,Aikawa,1998/11/28
112,B,1,Sasaki,1999/10/30
In [110]: df = pd.read_csv("sample17.csv",parse_dates=["birth_date"],infer_datetime_format=True)
In [111]: df
Out[111]:
id class grade name birth_date
0 1 A 1 Satou 1999-09-21
1 3 B 1 Hashimoto 2000-02-15
2 15 B 3 Takahashi 1997-04-05
3 102 A 2 Aikawa 1998-11-28
4 112 B 1 Sasaki 1999-10-30
In [112]: df = pd.read_csv("sample17.csv",parse_dates=["birth_date"],infer_datetime_format=False) # デフォルトはFalse
In [113]: df
Out[113]:
id class grade name birth_date
0 1 A 1 Satou 1999-09-21
1 3 B 1 Hashimoto 2000-02-15
2 15 B 3 Takahashi 1997-04-05
3 102 A 2 Aikawa 1998-11-28
4 112 B 1 Sasaki 1999-10-30
特に見た目上の変化はありません。
日付データとして結合される前の列データを残す keep_date_col
parse_datesの解説で扱ったような、複数列にわたる時刻データを結合するとき、keep_date_col=True
にしておくと元の列データを消去せずに残しておきます。
sample18.csvのデータを再び使います。
id,class,grade,name,birth_y,birth_m,birth_d
001,A,1,Satou,1999,09,21
003,B,1,Hashimoto,2000,02,15
015,B,3,Takahashi,1997,04,05
102,A,2,Aikawa,1998,11,28
112,B,1,Sasaki,1999,10,30
In [121]: df = pd.read_csv("sample18.csv",parse_dates={'birth_date':["birth_y","birth_m","birth_d"]}, keep_date_col=True)
In [122]: df
Out[122]:
birth_date id class grade name birth_y birth_m birth_d
0 1999-09-21 1 A 1 Satou 1999 09 21
1 2000-02-15 3 B 1 Hashimoto 2000 02 15
2 1997-04-05 15 B 3 Takahashi 1997 04 05
3 1998-11-28 102 A 2 Aikawa 1998 11 28
4 1999-10-30 112 B 1 Sasaki 1999 10 30
日付データへの変換する処理を指定する date_parser
日付データへの変換する処理を関数で指定することが可能です。以下のデータsample19.csvを使います。
id,class,grade,name,birth
001,A,1,Satou,1999/09/21 12:11
003,B,1,Hashimoto,2000/02/15 21:31
015,B,3,Takahashi,1997/04/05 09:11
102,A,2,Aikawa,1998/11/28 11:11
112,B,1,Sasaki,1999/10/30 17:38
datetime
モジュールを使って関数を定義して使ってみましょう。
In [123]: from datetime import datetime
In [124]: def parse_dates(x):
...: return datetime.strptime(x, '%Y/%m/%d %H:%M')
...:
In [125]: df = pd.read_csv("sample19.csv", parse_dates=["birth"],date_parser=parse_dates)
In [126]: df
Out[126]:
id class grade name birth
0 1 A 1 Satou 1999-09-21 12:11:00
1 3 B 1 Hashimoto 2000-02-15 21:31:00
2 15 B 3 Takahashi 1997-04-05 09:11:00
3 102 A 2 Aikawa 1998-11-28 11:11:00
4 112 B 1 Sasaki 1999-10-30 17:38:00
日/月のフォーマットを読み込む dayfrist
今度は以下のデータsample20.csvを使います。
id,class,grade,name,birth_date
001,A,1,Satou,1999/21/9
003,B,1,Hashimoto,2000/15/2
015,B,3,Takahashi,1997/05/04
102,A,2,Aikawa,1998/28/11
112,B,1,Sasaki,1999/30/10
先ほどのデータと変わって、年/日/月 の順番になっており、日付と月が逆になっています。このような場合、dayfirst=True
にすればこの形式の日付データも正しく読み込むことができます。
In [127]: df = pd.read_csv("sample20.csv",parse_dates=["birth_date"],dayfirst=True)
In [128]: df
Out[128]:
id class grade name birth_date
0 1 A 1 Satou 1999-09-21
1 3 B 1 Hashimoto 2000-02-15
2 15 B 3 Takahashi 1997-05-04
3 102 A 2 Aikawa 1998-11-28
4 112 B 1 Sasaki 1999-10-30
イテレータを返す iterator
iterator=True
にするとファイルを読み込むのではなくイテレータとして扱うことができます。TextFileReaderオブジェクトとして返されます。
sample1.csvのデータを使います。
class,grade,name
A,1,Satou
B,1,Hashimoto
B,3,Takahashi
A,2,Aikawa
get_chunk()
で中身を呼び出すことが可能です。
In [176]: df = pd.read_csv("sample1.csv", iterator=True)
In [177]: df.get_chunk(1)
Out[177]:
class grade name
0 A 1 Satou
In [178]: df.get_chunk(3)
Out[178]:
class grade name
1 B 1 Hashimoto
2 B 3 Takahashi
3 A 2 Aikawa
小分けにして処理をする chunksize
こちらもitearator=True
と同様にTextFileReader
オブジェクトを返すものとなっていますが1回あたりのファイルサイズをあらかじめ指定することができ50行ごとに読み込みたいならchunksize=50
のように指定することが可能です。
sample1.csvのデータを使います。
class,grade,name
A,1,Satou
B,1,Hashimoto
B,3,Takahashi
A,2,Aikawa
In [179]: iterate = pd.read_csv("sample1.csv", chunksize=2)
In [180]: for row in iterate:
...: print(row)
...: print("next\n")
...:
class grade name
0 A 1 Satou
1 B 1 Hashimoto
next
class grade name
2 B 3 Takahashi
3 A 2 Aikawa
next
こちらの方が扱いやすいと思うのでおすすめです。
圧縮フォーマットを指定して読み込む compression
デフォルトではファイル名の拡張子から圧縮フォーマットを推測して解凍してくれますが、これを個別に指定することも可能です。例えば、以下のファイルを圧縮したsample1.zipのデータを使います。
class,grade,name
A,1,Satou
B,1,Hashimoto
B,3,Takahashi
A,2,Aikawa
In [183]: df = pd.read_csv("sample1.zip") # デフォルトの設定でも読み込むことは可能
In [184]: df
Out[184]:
class grade name
0 A 1 Satou
1 B 1 Hashimoto
2 B 3 Takahashi
3 A 2 Aikawa
In [185]: df = pd.read_csv("sample1.zip", compression="zip") # zipファイルであることを明記して読み込ませる
In [186]: df
Out[186]:
class grade name
0 A 1 Satou
1 B 1 Hashimoto
2 B 3 Takahashi
3 A 2 Aikawa
1000の位ごとにおかれる区切り文字を認識する thousands
たとえば1,000のように数値をみやすくするためにカンマが使われることがあるが、カンマはcsvファイルの区切り文字として使われる文字なのでデータを読み込む際Pandasはこれを区切り文字として認識してしまいます。それを回避するためにthousands
引数に1000の位ごとに置かれる文字列を指定しておく必要があります。
また、クオーテーションマークで数字を囲わないと位の区切り文字を認識してくれないので注意しましょう。
name,price
A,"12,000"
B,"13,231"
C,"145,215"
以上のデータsample21.csvを使います。
In [193]: df = pd.read_csv("sample21.csv",thousands=",")
In [194]: df
Out[194]:
name price
0 A 12000
1 B 13231
2 C 145215
In [195]: df.dtypes
Out[195]:
name object
price int64
dtype: object
小数点の値を指定する decimal
ヨーロッパのデータ形式では小数点として.
ではなく,
を使うことがあるみたいです。そういったときにはdecimal
で個別に指定する必要があります。
以下のデータsample22.csvを使います。
name,amount
water,"123,23"
oil,"22,22"
alcohol,"3,12"
In [196]: df = pd.read_csv("sample22.csv",decimal=",")
In [197]: df
Out[197]:
name amount
0 water 123.23
1 oil 22.22
2 alcohol 3.12
浮動小数を読み込むコンバータを指定する float_precision
Cエンジンがどのコンバーターを使えば良いのかを指定します。Noneなら一般的なものが使われます。high
のときは高精度のコンバーターを使用し、round-trip
のときはround-tripコンバーターを使用します。
以下のデータsample23.csvを使います。
name,amount
water,123.01234567890123456789
oil,22.01234567890123456789
alcohol,3.01234567890123456789
In [198]: df = pd.read_csv("sample23.csv",float_precision="None") # これがデフォルト
In [199]: df
Out[199]:
name amount
0 water 123.012346
1 oil 22.012346
2 alcohol 3.012346
In [200]: df_2 = pd.read_csv("sample23.csv",float_precision="high")
In [201]: df_2
Out[201]:
name amount
0 water 123.012346
1 oil 22.012346
2 alcohol 3.012346
In [202]: df_3 = pd.read_csv("sample23.csv",float_precision="round-trip")
In [203]: df_3
Out[203]:
name amount
0 water 123.012346
1 oil 22.012346
2 alcohol 3.012346
特に大きな違いはみられませんでした。
行ごとの区切り文字を指定する lineterminator
改行記号をここで設定できます。\n
以外の文字でも読み込むことが可能です。長さ1の文字列しか指定できないので注意しましょう。
ここではsample24.txtのデータを使います。
class,grade,name\A,1,Satou\B,1,Hashimoto\B,3,Takahashi\A,2,Aikawa
ここでは区切り文字を\
を使うことにしました。
In [210]: df = pd.read_csv("sample24.txt",lineterminator="\\") # エスケープするのを忘れないように
In [211]: df
Out[211]:
class grade name
0 A 1 Satou
1 B 1 Hashimoto
2 B 3 Takahashi
3 A 2 Aikawa
引用を示すときに使う文字を指定する quotechar
文字列内のクオーテーションマークを指定することができます。
長さ1の文字列しか指定できないことに注意して使ってみましょう。引用部分では区切り文字があっても無視されます。
ここではsample25.csvのデータを使います。
name,text
A,<this quotation, is used<
B,<He said you,are lucky\n<
<
をクオーテーションマーク代わりに使っています。
In [253]: df = pd.read_csv("sample25.csv", quotechar='<')
In [254]: df
Out[254]:
name text
0 A this quotation, is used
1 B He said you,are lucky\n
クオーテーションの中にある文字列の処理の仕方を指定する quoting
quoting
はクオーテーションで囲まれたデータに対してどのような処理をするかを指示するもので、以下のモードが存在します。
- 0 :
QUOTE_MINIMAL
- 1 :
QUOTE_ALL
- 2 :
QUOTE_NONNUMERIC
- 3 :
QUOTE_NONE
番号かモードの名称で切り替えをします。デフォルトでは0のQUOTE_MINIMAL
。quotechar
で指定された文字(デフォルトは"
)によって囲まれた部分のみをクオーテーション扱いにするものです。
1のQUOTE_ALLはそのようなクオーテーションの文字列関係なく全てを引用文字列とみてもってきます。
2のQUOTE_NONNUMERICは非数値データ以外は全て引用します。
3のQUOTE_NONEはクオートする文字があってもクオートせず、カンマがあれば必ずデータを区切るようになります。これを回避するにはescapechar
でエスケープする文字列を指定する必要があります。
Pythonの公式ドキュメントで以下のような説明がされています。
csv.QUOTE_ALL
writer オブジェクトに対し、全てのフィールドをクオートするように指示します。
csv.QUOTE_MINIMAL
writer オブジェクトに対し、 delimiter 、 quotechar または lineterminator に含まれる任意の文字のような特別な文字を含むフィールドだけをクオートするように指示します。
csv.QUOTE_NONNUMERIC
writer オブジェクトに対し、全ての非数値フィールドをクオートするように指示します。 reader に対しては、クオートされていない全てのフィールドを float 型に変換するよう指示します。
csv.QUOTE_NONE
writer オブジェクトに対し、フィールドを決してクオートしないように指示します。現在の delimiter が出力データ中に現れた場合、現在設定されている escapechar 文字が前に付けられます。 escapechar がセットされていない場合、エスケープが必要な文字に遭遇した writer は Error を送出します。 reader に対しては、クオート文字の特別扱いをしないように指示します。
ここではsample26.csvのデータを使います。
name,text
A,"this 3 quotation, is used",3
B,"He said you,are 7 lucky ",5
全てのモードを試してみましょう。
In [263]: df_minimal = pd.read_csv("sample26.csv", quoting=0)
In [264]: df_minimal
Out[264]:
name text
A this 3 quotation, is used 3
B He said you,are 7 lucky 5
In [265]: df_all = pd.read_csv("sample26.csv",quoting=1) # 全部引用
In [266]: df_all
Out[266]:
name text
A this 3 quotation, is used 3
B He said you,are 7 lucky 5
In [267]: df_nonnumeric = pd.read_csv("sample26.csv",quoting=2) # 数値データ以外引用
In [268]: df_nonnumeric
Out[268]:
name text
A this 3 quotation, is used 3.0
B He said you,are 7 lucky 5.0
In [269]: df_none = pd.read_csv("sample26.csv", quoting=3) # 引用しない
In [270]: df_none
Out[270]:
name text
A "this 3 quotation is used" 3
B "He said you are 7 lucky " 5
In [271]: df_none.index
Out[271]:
MultiIndex(levels=[['A', 'B'], ['"He said you', '"this 3 quotation']],
labels=[[0, 1], [1, 0]])
In [272]: df_all.index
Out[272]: Index(['A', 'B'], dtype='object')
In [273]: df_nonnumeric.index
Out[273]: Index(['A', 'B'], dtype='object')
In [274]: df_minimal.index
Out[274]: Index(['A', 'B'], dtype='object')
クオーテーションとして指定した文字を文字列として認識する doublequote
doublequote=True
にすると""
とすればクオーテーションが文字列として認識されるようになります。
ここではsample27.csvのデータを使います。
name,text,number
A,"this ""quotation, is used",3
B,"He said you,are lucky",5
In [290]: df = pd.read_csv("sample27.csv",doublequote=True) # doublequote=Trueにするとうまく読み込める
In [291]: df
Out[291]:
name text number
0 A this "quotation, is used 3
1 B He said you,are lucky 5
In [292]: df = pd.read_csv("sample27.csv",doublequote=False) # doublequote=Falseだとうまくいかない
In [293]: df
Out[293]:
name text number
A this "quotation is used" 3.0
B He said you,are lucky 5 NaN
特殊文字をエスケープさせる文字を指定する escapechar
quoting=QUOTE_NONE(クオーテーションマークが無効になっている)のとき特殊文字をエスケープさせる文字を指定します。
sample28.csvのデータを使います。
name,text,number
A,this quotation\, is used",3
B,"He said you\,are lucky\"",5
バックスラッシュ\
エスケープさせる文字として使われているのでescapechar="\"
で指定します。
In [295]: df = pd.read_csv("sample28.csv", escapechar="\\")
In [296]: df
Out[296]:
name text number
0 A this quotation, is used" 3
1 B He said you,are lucky" 5
コメントアウトする文字列を指定する comment
以下のデータsample13.csvを用意します。
# ここから
class,grade,name
# ここまでがヘッダー
A,1,Satou
B,1,Hashimoto
B,3,Takahashi
A,2,Aikawa
ここのコメントアウトで使われている文字列は#
なのでcomment='#'
とすればコメントを読み飛ばしてくれます。
In [298]: df = pd.read_csv("sample13.csv", comment='#')
In [299]: df
Out[299]:
class grade name
0 A 1 Satou
1 B 1 Hashimoto
2 B 3 Takahashi
3 A 2 Aikawa
ファイルを読み込む文字コードを指定する encoding
基本的にcsvファイルやUTF-8
で保存されていますが、他の文字コードで保存されているケースも存在します。
class,grade,name
A,1,Satou
B,1,Hashimoto
B,3,Takahashi
A,2,Aikawa
これをsample29.csvとして保存します。このとき文字コードをShift JIS
にして保存してください。
では文字コードを指定して読み込みます。
In [300]: df = pd.read_csv("sample29.csv",encoding="shift_jis")
In [301]: df
Out[301]:
class grade name
0 A 1 Satou
1 B 1 Hashimoto
2 B 3 Takahashi
3 A 2 Aikawa
csvファイルの読み込み方を一括で指定する dialect
csvファイルの読み込み方を一括で指定するにはcsvモジュールのDialectクラスを使用することもできます。
DialectクラスについてはPythonの公式ドキュメントに書いてあるのでこちらを参照にしてください。
このクラスでdelimiter
,doublequote
,escapechar
,lineterminator
,quotechar
,quoting
,skipinitialspace
をまとめて指定することが可能です。
dialect
を指定した状態でこれらの引数を個別に設定するとエラーが返ってくるので気をつけてください。
以下のデータsample2.csvを使います。
id;class;grade;name
0;A;1;Satou
1;B;1;Hashimoto
2;B;3;Takahashi
3;A;2;Aikawa
csv.excel()でExcelで生成されたcsvファイルを読み込むためのDialectクラスが生成されます。
In [324]: import csv
In [328]: dialect = csv.excel()
In [329]: dialect.delimiter = ";"
In [330]: df = pd.read_csv("sample2.csv",dialect=dialect)
In [331]: df
Out[331]:
id class grade name
0 0 A 1 Satou
1 1 B 1 Hashimoto
2 2 B 3 Takahashi
3 3 A 2 Aikawa
MultiIndexを作成しようとする tupleize_cols
tupleize_cols=True
にしておくとカラムラベルをMultiIndexに変換しようとします。 しかし、これは非推奨となっているためあまり使わないようにしましょう。
サイズに合わない行が出てきた時の対処の仕方を指定する error_bad_lines
class,grade,name
A,1,Satou,12324515
B,1,Hashimoto
B,3,Takahashi
A,2,Aikawa
例えば上記のようなデータsample30.csvがあったとします。これをそのまま読み込むとエラーがそのまま返ってきて読み込むことができません。
ここでerror_bad_lines=False
とすると、エラーを返さず、データを読み込みます。
In [365]: df = pd.read_csv("sample30.csv",error_bad_lines=False, index_col=False)
In [366]: df
Out[366]:
class grade name
0 A 1 Satou
1 B 1 Hashimoto
2 B 3 Takahashi
3 A 2 Aikawa
多すぎるデータを検出したときに警告メッセージを出すかどうか指定する warm_bad_lines
先ほどと同じデータsample31.csvを考えます。
a,b,c
1,2,3
4,5,6,7
8,9,10
これで、warm_bad_lines=True
にしてみます。
In [367]: df = pd.read_csv("sample31.csv",error_bad_lines=False, warn_bad_lines=True)
b'Skipping line 3: expected 3 fields, saw 4\n'
In [368]: df
Out[368]:
a b c
0 1 2 3
1 8 9 10
まとめ
非常に長い解説になってしまいましたが、pandasのread_csv関数にはこれだけの豊富な機能が備わっています。実現したい操作があったら、本記事を適宜参照して使ってみてください。