本記事では引数の多いread_csv関数とread_table関数について解説します。全ての引数についての説明をします。関数を使用する際の辞書代わりにお使いください。

read_csvread_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 (省略可能)初期値None
iterator=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

sepdelimiterで区切り文字を指定できます。

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にすれば空白文字が区切り文字となります。

delimitersepに他の文字が指定されているとエラーになるので注意してください。(デフォルトの状態にしておけば問題ありません。)

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の名前で保存します。このアンケート結果のYesTrueに、NoFalseに変換します。

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は追加の設定は行えませんが、デフォルトの設定を適用させるかどうかを指定することができます。

先ほどと同じデータを使ってみます。

sample15.csv

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_MINIMALquotecharで指定された文字(デフォルトは")によって囲まれた部分のみをクオーテーション扱いにするものです。

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関数にはこれだけの豊富な機能が備わっています。実現したい操作があったら、本記事を適宜参照して使ってみてください。

参考