pythonでcsvを読む方法 - 標準ライブラリ, pandas, numpy


このエントリーをはてなブックマークに追加

pythoncsvを読み込む方法についてまとめました。ライブラリによって微妙に読み込み方が異なるので大変です。

この記事では、以下のdata.csvを読み込む場合を考えます。最初の行がヘッダ行で、それ以降の行がデータ行です。

a,b,c
2,5.6,1
1,7.0,0
3,6.2,1
3,7.9,1

方法1: 標準ライブラリのcsvを使う方法

csv.readerオブジェクトを使って一行ずつ読んでいく方法です。ヘッダ行の部分を特別扱いする必要があります。

import csv
def open_with_python_csv(filename):
    data = []
    with open(filename, 'r') as filename:
        reader = csv.reader(filename)
        # ヘッダ行は特別扱い
        header = next(reader)
        # 中身
        for row in reader:
            data.append(row)
    return header, data

header, data = open_with_python_csv(csvfile)

header, dataをprintすると以下のようになります。

header: ['a', 'b', 'c']
data: [['2', '5.6', '1'], ['1', '7.0', '0'], ['3', '6.2', '1'], ['3', '7.9', '1']]

文字列ではなく数字が必要な場合は別途手動で変換が必要です。

高機能とはいえませんが、標準ライブラリのためどの環境でも使えるのが強みと言えます。

方法2: pandasを使う方法

データ分析ツールのpandasを使うこともできます。

import pandas

def open_with_pandas(filename):
    df = pandas.read_csv(filename)
    header = df.columns.values.tolist()
    data = df.values
    return df, header, data

df, header, data = open_with_pandas(csvfile)

header, dataをprintすると以下のようになります。

header: ['a', 'b', 'c']
data: [[ 2.   5.6  1. ]
 [ 1.   7.   0. ]
 [ 3.   6.2  1. ]
 [ 3.   7.9  1. ]]

header, dataの型はそれぞれlist, numpy.ndarrayです。 数値が自動的に適当な型で保持されています。数値の型を指定することもできますが本記事の内容を超えます。 pandasを使ってデータの処理を行いたいときにはよい選択です。

方法3: numpyを使う方法

numpyにも、csvの読み込みに使える関数がloadtxt()とgenfromtxt()の2つ存在します。

numpy.loadtxt()を使う場合

もしヘッダ行が不要な場合は、以下のようにskiprowsを設定すればOKです。デリミタを明示的に指定する必要があるのに注意が必要です。

import numpy as np
def open_with_numpy_loadtxt(filename):
    data = np.loadtxt(filename, delimiter=',', skiprows=1)
    return data

data = open_with_numpy_loadtxt(csvfile)

dataの型はnumpy.ndarrayです。

ヘッダ行も読み込みたい場合は、以下の2通りの方法があるようです。まず一つ目。

import numpy as np
def open_with_numpy_loadtxt_2(filename):
    with open(filename, 'r') as file:
        line = file.readline()
        header = line.strip().split(',')
        data = np.loadtxt(file, delimiter=',')
    return header, data

header, data = open_with_numpy_loadtxt_2(csvfile)

そして二つ目。

import numpy as np
def open_with_numpy_loadtxt_3(filename):
    with open(filename, 'r') as file:
        lines = list(file)
    header = lines[0].strip().split(',')
    data = np.loadtxt(lines[1:], delimiter=',')
    return header, data

header, data = open_with_numpy_loadtxt_3(csvfile)

numpy.genfromtxt()を使う場合

genfromtxt()はloadtxt()に比べて、欠損値を埋める機能などがあり高機能だそうです。

まずはヘッダ行を読み飛ばす方法です。デリミタの指定が必要なのはloadtxt()と同じです。

def open_with_numpy_genfromtxt(filename):
    data = np.genfromtxt(filename, delimiter=',', skip_header=1)
    return data```

data = open_with_numpy_genfromtxt(csvfile)

ヘッダ行を解析する方法がまだ分かっていません。genfromtxt()にnames=Trueという引数を加えると、コラムに名前が付いたnumpy.ndarrayが得られるのですが、二次元配列ではなくなってしまいます。

import numpy as np
def open_with_numpy_genfromtxt_2(filename):
    data = np.genfromtxt(filename, delimiter=',', names=True)
    header = data.dtype.names
    return header, data

header, data = open_with_numpy_genfromtxt_2(csvfile)
# data[0]['a']などとアクセス可能

全コード

最後に、この記事を書くのに使ったスクリプトを貼っておきます。

read a csv file using python