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を使う上でも最も基礎的でありながら非常に重要な部分となっているので、是非使いこなせるようになりましょう。

参考