CSV形式のデータは多くの人が扱えることや、データ形式がシンプルなことからデータ分析でもよく使われます。Pandasを使ってデータ分析をするときも、CSV形式が読み込めると便利です。そこで本記事では、
- read_csv関数の簡単な使い方
について解説していきます。
詳しい解説はまた他の記事で扱います。
引数が膨大なので、ここではよく使われるであろう引数について解説します。
この記事で使用するサンプルファイルは以下のリンクからダウンロードできます。
sample1.csv sample2.csv sample3.csv sample4.csv sample5.csv sample6.csv sample7.csv sample8.csv sample9.csv
read_csv関数
読み込み方
read_csv
関数は名前の通り、csv
形式のファイルをPandasのDataFrame
へと読み取る関数となっています。例えば、以下のようなcsv形式のファイルがあったとします。
class,grade,name
A,1,Satou
B,1,Hashimoto
B,3,Takahashi
A,2,Aikawa
以上のファイルをsample1.csv
で保存しておきます。ここでPythonを起動して、このcsv形式のファイルをPandasを使って読み取ってみると、以下のようになります。
In [1]: import pandas as pd
In [2]: sample = pd.read_csv("sample1.csv")
In [3]: sample
Out[3]:
class grade name
0 A 1 Satou
1 B 1 Hashimoto
2 B 3 Takahashi
3 A 2 Aikawa
このようにカラムラベルがついた状態でcsvの中身をDataFrameに読み取ることができました。
sep
区切り文字の指定次は以下のファイルの場合を考えて見ましょう。以下のファイルはcsvの区切り文字がカンマではなく、スペース表記になっているものです。
class grade name
A 1 Satou
B 1 Hashimoto
B 3 Takahashi
A 2 Aikawa
これをsample2.csv
の名前で保存します。次のように,
(カンマ)区切りではなく
(スペース)区切りのとき、sep=" "
とすれば読み込めます。
In [9]: sample2 = pd.read_csv("sample2.csv", sep=" ")
In [10]: sample2
Out[10]:
class grade name
0 A 1 Satou
1 B 1 Hashimoto
2 B 3 Takahashi
3 A 2 Aikawa
index_col
インデックスラベルの指定sample3.csv
で以下のファイルを保存します。
id,class,grade,name
001,A,1,Satou
003,B,1,Hashimoto
015,B,3,Takahashi
102,A,2,Aikawa
このとき、id
をインデックスラベルにしたいときは、index_col = "id"
と指定します。
In [11]: sample3 = pd.read_csv("sample3.csv", index_col="id")
In [12]: sample3
Out[12]:
class grade name
id
1 A 1 Satou
3 B 1 Hashimoto
15 B 3 Takahashi
102 A 2 Aikawa
列名の有無 header
では、次のようにコラム名が存在しない時を考えます。
001,A,1,Satou
003,B,1,Hashimoto
015,B,3,Takahashi
102,A,2,Aikawa
このときはheader
が存在しないということなので、header=None
とすればうまく読み込んでくれます。
In [13]: sample4 = pd.read_csv("sample4.csv", header=None)
In [14]: sample4
Out[14]:
0 1 2 3
0 1 A 1 Satou
1 3 B 1 Hashimoto
2 15 B 3 Takahashi
3 102 A 2 Aikawa
列(カラム)名の指定 names
カラム名を指定したいときはnames
引数で指定します。
In [15]: sample4_2 = pd.read_csv("sample4.csv", header=None, names=["id","class","grade","name"])
In [16]: sample4_2
Out[16]:
id class grade name
0 1 A 1 Satou
1 3 B 1 Hashimoto
2 15 B 3 Takahashi
3 102 A 2 Aikawa
このとき、新しいname
に対応するカラム名を指定すればインデックスラベルも指定可能です。
In [17]: sample4_3 = pd.read_csv("sample4.csv", header=None, names=["id","class","grade","name"], index_col="id")
In [18]: sample4_3
Out[18]:
class grade name
id
1 A 1 Satou
3 B 1 Hashimoto
15 B 3 Takahashi
102 A 2 Aikawa
特定の行だけ読み飛ばす skiprows
# コメント
id,class,grade,name
# コメント
# コメント
001,A,1,Satou
003,B,1,Hashimoto
015,B,3,Takahashi
102,A,2,Aikawa
このようなsample5.csv
があったとします。コメントがいくつかあって読み込めないですね。
このときは、skiprows
を使って読み込まない行を指定することが可能です。
In [19]: sample5 = pd.read_csv("sample5.csv",skiprows=[0,2,3])
In [20]: sample5
Out[20]:
id class grade name
0 1 A 1 Satou
1 3 B 1 Hashimoto
2 15 B 3 Takahashi
3 102 A 2 Aikawa
読み込む行数を制限することもできます。
In [21]: sample5_2 = pd.read_csv("sample5.csv",skiprows=[0,2,3],nrows=2)
In [22]: sample5_2
Out[22]:
id class grade name
0 1 A 1 Satou
1 3 B 1 Hashimoto
欠損値として読み込む値を指定する na_values
次に、以下のように欠損値がある場合を考えてみましょう。
001,A,NULL,Satou
003,,1,Hashimoto
015,B,3,Takahashi
102,A,2,-
これをsample6.csv
の名前で保存します。
headerがないことに注意して一旦読み込んでみます。
In [8]: sample6 = pd.read_csv("sample6.csv", header=None)
In [9]: sample6
Out[9]:
0 1 2 3
0 1 A NaN Satou
1 3 NaN 1.0 Hashimoto
2 15 B 3.0 Takahashi
3 102 A 2.0 -
In [10]: sample6.isnull() # どの要素が欠損値として認識されているか確かめる
Out[10]:
0 1 2 3
0 False False True False
1 False True False False
2 False False False False
3 False False False False
名前の列の-
が欠損値として認識されませんでしたね。
これも欠損値として含めるにはna_values
引数を使って指定します。
ここで指定すると欠損値として認識する値のリストを丸ごと更新するのではなく、引数として指定した値をそのリストにつけ加える形になります。
なので、従来欠損値として読み込んでいた値も従来通り欠損値として読み込んでくれます。
In [12]: sample6 = pd.read_csv("sample6.csv", header=None, na_values=['-'])
In [13]: sample6
Out[13]:
0 1 2 3
0 1 A NaN Satou
1 3 NaN 1.0 Hashimoto
2 15 B 3.0 Takahashi
3 102 A 2.0 NaN
分割して読み込む chunksize
データの量が多すぎて少しずつ読み取って処理していきたいというときはchunkszie
を指定するといいでしょう。
id,class,grade,name
001,A,1,Satou
003,B,1,Hashimoto
015,B,3,Takahashi
102,A,2,Aikawa
112,B,1,Sasaki
これを2行ずつ読み取っていきましょう。
In [14]: chunk_sample7 = pd.read_csv('sample7.csv', chunksize=2)
In [15]: chunk_sample7
Out[15]: <pandas.io.parsers.TextFileReader at 0x10fd610f0>
In [16]: for pieces in chunk_sample7:
...: print("iterate")
...: print(pieces["name"])
...:
iterate
0 Satou
1 Hashimoto
Name: name, dtype: object
iterate
2 Takahashi
3 Aikawa
Name: name, dtype: object
iterate
4 Sasaki
Name: name, dtype: object
このように分割して読み取ることができます。
文字コードの指定 encoding
id,class,grade,name
001,A,1,佐藤
003,B,1,橋下
015,B,3,高橋
102,A,2,相川
112,B,1,佐々木
上のデータをsample8.csv
の名前で保存してください。
このとき文字コードはShift JIS
を選んでください。
とりあえず読み込んでみます。
In [39]: sample8 = pd.read_csv("sample8.csv")
---------------------------------------------------------------------------
(エラーメッセージが表示される)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8d in position 0: invalid start byte
引数encoding
で文字コードをshift_jis
と指定して読み込みます。
In [42]: sample8 = pd.read_csv("sample8.csv", encoding="shift_jis")
In [43]: sample8
Out[43]:
id class grade name
0 1 A 1 佐藤
1 3 B 1 橋下
2 15 B 3 高橋
3 102 A 2 相川
4 112 B 1 佐々木
うまく読み込めました。
TimeStamp型として読み込む列を指定する parse_dates
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
上のような誕生日が入っているデータを考えます。
これをsample9.csv
の名前で保存しておきます。
birth_date
カラムを日付データとして読み込むにはparse_dates
に指定してあげればいいです。
In [48]: sample9 = pd.read_csv("sample9.csv", parse_dates=["birth_date"])
In [49]: sample9
Out[49]:
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 [51]: type(sample9['birth_date'][1])
Out[51]: pandas._libs.tslibs.timestamps.Timestamp
まとめ
今回は、csvファイルを読み込む関数であるread_csv
関数の使い方についてまとめました。
この記事で扱った引数で大体の操作はできるはずです。
ファイルの読み込みはPandasを使う上でも最も基礎的でありながら非常に重要な部分となっているので、是非使いこなせるようになりましょう。
参考
- Python for Data Analysis 2nd edition –Wes McKinney(書籍)
- pandasでcsv/tsvファイル読み込み(read_csv, read_table) - note.nkmk.me
- pandas.read_csv - pandas 0.23.3 documentation