BETA

pandasでCSV読み込み

投稿日:2020-02-16
最終更新:2020-02-16

Pyhtonで機械学習を行うとき、入力データをCSVファイルから取得することがあります。

Pythonで機械学習と言えばnumpyが欠かせませんが、CSVファイルの読み込みはpandasで行うと大変便利です。数行のコードで大抵のことは出来てしまいます。

pandaで読み込んだデータをnumpy形式(ndarray)に変換して、機械学習用のライブラリに渡してあげればOKです。

公式のリファレンスを参考に、色々なCSVファイルを読み込んでみました。

read_csvで読み込み

A,B,C,D,E  
0,1,2,3,4  
5,6,7,8,9  
10,11,12,13,14  

上記のようなCSVファイルを読み込む場合、以下のように書くと、

# coding: utf-8  
import pandas as pd  
df = pd.read_csv('foo.csv')  
print(df)  
#     A   B   C   D   E  
# 0   0   1   2   3   4  
# 1   5   6   7   8   9  
# 2  10  11  12  13  14  

デフォルトでは、先頭行をタイトル行(A,B,C,D,E)として読み込みます。
各行のインデックス(0,1,2)は自動で付与されます。

タブ区切りのファイル読み込み

A___B___C___D___E  
0___1___2___3___4  
5___6___7___8___9  
10___11___12___13___14  

タブ区切りのファイルを読み込む場合はsep='\t'を指定します。

df = pd.read_csv('foo.csv', sep='\t')  
print(df)  
#     A   B   C   D   E  
# 0   0   1   2   3   4  
# 1   5   6   7   8   9  
# 2  10  11  12  13  14  

カンマとタブ区切りに限らず、sepで区切り文字を指定できます。

タイトル行が無い場合

0,1,2,3,4  
5,6,7,8,9  
10,11,12,13,14  

タイトル行の無いCSVファイルを読み込む場合はheader=Noneを指定します。

df = pd.read_csv('foo.csv', header=None)  
print(df)  
#     0   1   2   3   4  
# 0   0   1   2   3   4  
# 1   5   6   7   8   9  
# 2  10  11  12  13  14  

列の名前は自動で付与してくれます。

タイトル行が複数の場合

A,A,B,B,C  
a,b,a,b,a  
0,1,2,3,4  
5,6,7,8,9  
10,11,12,13,14  

タイトル行が複数ある場合はheader=[0,1]のように、リストで行番号を指定します。

df = pd.read_csv('foo.csv', header=[0,1])  
print(df)  
#     A       B       C  
#     a   b   a   b   a  
# 0   0   1   2   3   4  
# 1   5   6   7   8   9  
# 2  10  11  12  13  14  

任意の列名を付ける

0,1,2,3,4  
5,6,7,8,9  
10,11,12,13,14  

タイトル行を自分で付ける場合はnamesに名称を指定します。

df = pd.read_csv('foo.csv', names=['a','b','c','d','e'])  
print(df)  
#     a   b   c   d   e  
# 0   0   1   2   3   4  
# 1   5   6   7   8   9  
# 2  10  11  12  13  14  

インデックス列を指定する

,A,B,C,D,E  
i,0,1,2,3,4  
j,5,6,7,8,9  
k,0,1,2,3,4  

インデックス列を指定する場合はindex_colに整数を指定します。

df = pd.read_csv('foo.csv', index_col=0)  
print(df)  
#    A  B  C  D  E  
# i  0  1  2  3  4  
# j  5  6  7  8  9  
# k  0  1  2  3  4  

列名を指定することも出来ます。以下はA列を指定した例です。

df = pd.read_csv('foo.csv', index_col='A')  
print(df)  
#   Unnamed: 0  B  C  D  E  
# A                         
# 0          i  1  2  3  4  
# 5          j  6  7  8  9  
# 0          k  1  2  3  4  

インデックス列を複数指定する

,,A,B,C,D,E  
i,k,0,1,2,3,4  
i,l,5,6,7,8,9  
j,m,0,1,2,3,4  

インデックス列を複数指定する場合はindex_col=[0,1]のように、リストで列番号を指定します。

df = pd.read_csv('foo.csv', index_col=[0,1])  
print(df)  
#      A  B  C  D  E  
# i k  0  1  2  3  4  
#   l  5  6  7  8  9  
# j m  0  1  2  3  4  

列名を複数指定する場合も同様に、リストで指定します。

df = pd.read_csv('foo.csv', index_col=['A','B'])  
print(df)  
#     Unnamed: 0 Unnamed: 1  C  D  E  
# A B                                 
# 0 1          i          k  2  3  4  
# 5 6          i          l  7  8  9  
# 0 1          j          m  2  3  4  

名称が付いていない列はUnnamed: 〜が自動で付与されます。

指定した列のみを読み込む

,A,B,C,D,E  
i,0,1,2,3,4  
j,5,6,7,8,9  
k,0,1,2,3,4  

指定した列のみを読み込む場合はusecols[0,1]のようにリスト形式で指定します。

df = pd.read_csv('foo.csv', usecols=[1,2])  
print(df)  
#    A  B  
# 0  0  1  
# 1  5  6  
# 2  0  1  

列名を指定することも可能です。

df = pd.read_csv('foo.csv', usecols=['A','E'])  
print(df)  
#    A  E  
# 0  0  4  
# 1  5  9  
# 2  0  4  

また、ラムダ式で条件を設定し、条件に合致する列のみを読み込むことも出来ます。

df = pd.read_csv('foo.csv', usecols=lambda s: s < 'C')  
print(df)  
#    A  B  
# 0  0  1  
# 1  5  6  
# 2  0  1  

スペースを無視したい場合

no, name,   age  
1,  Taro,   15  
2,  Jiro,   10  
3,  Saburo, 5  

上記のように、区切り文字の後ろに半角スペースが含まれる場合、半角スペースも一緒に読み込まれてしまいます。数値の場合は問題ないのですが、列名や文字列データに余分なスペースが含まれてしまいます。

df = pd.read_csv('foo.csv')  
print(df)  
#    no      name     age  
# 0   1      Taro      15  
# 1   2      Jiro      10  
# 2   3    Saburo       5  
print(df.columns)  
# Index(['no', ' name', '   age'], dtype='object')  

半角スペースを飛ばしたい場合はskipinitialspace=Trueを指定します。

df = pd.read_csv('foo.csv', skipinitialspace=True)  
print(df)  
#    no    name  age  
# 0   1    Taro   15  
# 1   2    Jiro   10  
# 2   3  Saburo    5  
print(df.columns)  
# Index(['no', 'name', 'age'], dtype='object')  

指定した行を飛ばす

foo.csv  

A,B,C,D,E  
0,1,2,3,4  
5,6,7,8,9  
10,11,12,13,14  

上記のように1,2行目は読込不要の場合はskiprows=[0,1]のように、リストで読込不要な行の番号を指定します。

df = pd.read_csv('foo.csv', skiprows=[0,1])  
print(df)  
#     A   B   C   D   E  
# 0   0   1   2   3   4  
# 1   5   6   7   8   9  
# 2  10  11  12  13  14  

na_values

A,B,C,D,E  
0,1,2,3,NG  
5,6,,,9  
-,-,12,13,14  

空白は、欠損=NaN(numpy.nan)として読み込まれます。

df = pd.read_csv('foo.csv')  
print(df)  
#    A  B     C     D   E  
# 0  0  1   2.0   3.0  NG  
# 1  5  6   NaN   NaN   9  
# 2  -  -  12.0  13.0  14  

空白以外にも欠損=NaNに指定したいデータがある場合はna_valuesで指定します。

df = pd.read_csv('foo.csv', na_values=['-','NG'])  
print(df)  
#      A    B     C     D     E  
# 0  0.0  1.0   2.0   3.0   NaN  
# 1  5.0  6.0   NaN   NaN   9.0  
# 2  NaN  NaN  12.0  13.0  14.0  

日付をdatatime型として読み込む

date,Temp.,Humidity  
2017/1/1,-1.1,10  
2017/1/2,-2.2,20  
2017/1/3,-3.3,30  

日付データはデフォルトでは、object型として読み込まれます。

df = pd.read_csv('foo.csv')  
print(df)  
#        date  Temp.  Humidity  
# 0  2017/1/1   -1.1        10  
# 1  2017/1/2   -2.2        20  
# 2  2017/1/3   -3.3        30  
print(df.dtypes)  
# date         object  
# Temp.       float64  
# Humidity      int64  
# dtype: object  

日付として読み込みたい列をparse_datesで指定します。
列番号で指定しても列名で指定しても動作します。
下記例ではparse_dates=['date']parse_dates=[0]に変えても同じように動作します。

df = pd.read_csv('foo.csv', parse_dates=['date'])  
print(df)  
#         date  Temp.  Humidity  
# 0 2017-01-01   -1.1        10  
# 1 2017-01-02   -2.2        20  
# 2 2017-01-03   -3.3        30  
print(df.dtypes)  
# date        datetime64[ns]  
# Temp.              float64  
# Humidity             int64  
# dtype: object  

データ型を指定する

no,name,age,height  
1,Taro,50,170  
2,Sachiko,40,160  
3,Masami,30,180  

データ型を指定しない場合、自動でデータ型を判定してくれますが、それでは不都合な場合もあります。上記例では"height"は実数型(float)で扱ってほしいのですが整数型(int)と判定されます。

df = pd.read_csv('foo.csv')  
print(df)  
#    no     name  age  height  
# 0   1     Taro   50     170  
# 1   2  Sachiko   40     160  
# 2   3   Masami   30     180  
print(df.dtypes)  
# no         int64  
# name      object  
# age        int64  
# height     int64  
# dtype: object  

データ型を指定したい場合にはdtypeで型を指定します。
np.int64np.float64"Int64"のように文字列で指定することも可能です。

import numpy as np  
df = pd.read_csv('foo.csv',   
                 dtype={'no': np.int64, 'name': object,   
                        'age': np.int64, 'height': np.float64} )  
print(df)  
#    no     name  age  height  
# 0   1     Taro   50   170.0  
# 1   2  Sachiko   40   160.0  
# 2   3   Masami   30   180.0  
print(df.dtypes)  
# no          int64  
# name       object  
# age         int64  
# height    float64  
# dtype: object  

より詳しいことを知りたい方は

pandas公式のUser GuideやCookbookにより詳しく使い方が載っています。
IO tools (text, CSV, HDF5, …) — pandas 1.0.1 documentation<
Cookbook — pandas 1.0.1 documentation

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

役に立つことから立たないことまで日々のアウトプットを綴る

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう