Up

CSVファイルの読み書き

 

CSVComma separated Values)ファイルの読み書きについて例を示す。

CSVファイルの例を図1に示す。

 

図1 CSVファイルsample1.csv

 

CSVファイルは値をコンマ,で区切って並べたものであり、ファイル拡張子は「.csv」である。図1のファイルsample1.csvをテキストエディタで開くと図2のようになっている。

 

図2 CSVファイルをエディタで開いたもの

 

CSVファイルはテキストファイルであるので、テキストファイルとして読み書きできるが、Pandasのライブラリを用いると、読み書きが簡単にできる。

まず、CSVファイルの読み込みについて説明して、次に書き出しについて説明する。

 

 

CSVファイルの読み込み

 

図1に示されているCSVファイルの読み込みを行う。

CSVファイルsample1.csvは、pandasの関数read_csvによって読み込むことができる。コードを次に示す。

 

data_csv = pandas.read_csv('sample1.csv', encoding='shift_jis')

 

引数encoding='shift_jis'は、ファイルに日本語が含まれているときに必要である。'shift_jis'が標準であるが、それでうまくいかないときは他のコードを設定する。Pythonのエディタで日本語を含むCSVファイルを作成したときは、'utf-8'である。図1のデータは、Excelで作成したものである。Excelで作成した図1のCSVファイルをPythonのエディタで開くときは、Pythonのエディタにコードが'shift_jis'であることを設定している。CSVファイルに日本語が含まれず、英語のみであれば、encoding='shift_jis'は要らない。

なお、PythonCSVファイルを作成したとき、日本語を含む場合は、Excelで開くと文字化けを起こす。Calcの場合はインポート/文字列を「Unicode(UTF-8)」に設定すると文字化けを起こさない。

次のスクリプトでCSVファイルとExcelファイルを作成した。

 

import pandas as pd

 

data = {'A':['','',''], 'B':[1,2,3]}

pd.DataFrame(data).to_csv('jp_sj.csv')

 

pd.DataFrame(data).to_excel('jp_sj.xlsx')

 

CSVファイルの方は、Excelでは文字化けを起こしているが、Calcの方は文字化けはない。

 

Excelファイル(*.xlsx)の場合は、ExcelCalcも文字化けなく表示されている。

 

 

 

読み込まれた内容は、pandasDataFrame型として表される。DataFrame型は配列のようなものであり、列がCSVファイルの第1行目の値をキーとする辞書型の感覚で使えるが、便利な関数が用意されている。

 

上のスクリプト

 

data_csv = pandas.read_csv('sample1.csv', encoding='shift_jis')

 

によって読み込んだ内容を、次のprint関数

 

print('data_csv =\n', data_csv)

 

で出力すると以下のようになる。

 

data_csv =

   ケース識別子  変数1  変数2  変数3

0     太郎  100   50    5

1     次郎  150   30    3

2     花子  120   70    7

 

第1列目には、0から始まるデータの通し番号(index)が出力されている。

第1行目は、CSVファイルの第1行目の値で、keyとして用いられる。

2行目以降、2列目より右側に、CSVデータの2行目以降が出力されている。

次のコードは、keyを出力するものである。

 

print('data_csv.keys() =\n', data_csv.keys())

 

実行すると、次の出力を得る。

 

data_csv.keys() =

 Index(['ケース識別子', '変数1', '変数2', '変数3'], dtype='object')

 

keyに対する値は、次のコードで確認できる。

 

for nm in data_csv.keys():

    print('key =',nm)

    print('data_csv[key] =\n', data_csv[nm])

 

実行すると、以下の出力を得る。

 

key = ケース識別子

data_csv[key] =

 0    太郎

1    次郎

2    花子

Name: ケース識別子, dtype: object

key = 変数1

data_csv[key] =

 0    100

1    150

2    120

Name: 変数1, dtype: int64

key = 変数2

data_csv[key] =

 0    50

1    30

2    70

Name: 変数2, dtype: int64

key = 変数3

data_csv[key] =

 0    5

1    3

2    7

Name: 変数3, dtype: int64

 

 

アトリビュートvaluesを用いるとkeyに対する値がndarray型の配列として得られる。次のコードではvaluesによって配列型として値を得ている。

 

for nm in data_csv.keys():

    print('key =',nm)

    print('data_csv[key].values \n', data_csv[nm].values)

 

実行すると、以下の出力を得る。

 

key = ケース識別子

data_csv[key].values

 ['太郎' '次郎' '花子']

key = 変数1

data_csv[key].values

 [100 150 120]

key = 変数2

data_csv[key].values

 [50 30 70]

key = 変数3

data_csv[key].values

 [5 3 7]

 

 

data_csvに読み込まれた値全体のndarray型の値を得るときは、keyを指定せずにvaluesを適用すればよい。次のコード

 

print('data_csv.vales =\n', data_csv.values)

 

を実行すると、以下の出力を得る。

 

data_csv.vales =

 [['太郎' 100 50 5]

 ['次郎' 150 30 3]

 ['花子' 120 70 7]]

 

 

ndarray型であるので、numpyの関数が利用できる。

次のコードは、CSVファイルの2列目以降の列ごとの和を求めるものである。

 

print(numpy.sum(data_csv.values.T[1:], axis=1))

 

実行すると次の出力を得る。

 

[370 150 15]

 

 

以上のスクリプトを1つのスクリプトにリスト1としてまとめた。

 

 

リスト1

 

import pandas

import numpy

 

data_csv = pandas.read_csv('sample1.csv', encoding='shift_jis')

print('data_csv =\n', data_csv)

print('data_csv.keys() =\n', data_csv.keys())

print()

for nm in data_csv.keys():

    print('key =',nm)

    print('data_csv[key] =\n', data_csv[nm])

print()

for nm in data_csv.keys():

    print('key =',nm)

    print('data_csv[key].values \n', data_csv[nm].values)

print()

print('data_csv.vales =\n', data_csv.values)

print()

print(numpy.sum(data_csv.values.T[1:], axis=1))

 

 

 

空白セルがある場合

 

CSVファイルに空白のセルがある場合、空白セルはNANNot a Number)に置き換えられる。

 

図3

 

図3のCSVファイルsample2.csvでは、2つのセルが空白である。

このファイルを次のコードで読み込み、出力してみる。

 

data_csv = pd.read_csv('sample2.csv', encoding='shift-jis')

print('DataFrame =\n', data_csv)

 

以下の出力を得る。

 

DataFrame =

   ケース識別子    変数1  変数2  変数3

0     太郎  100.0   50  5.0

1     次郎    NaN   30  3.0

2     花子  120.0   70  NaN

 

 

空白セルがNaNになっていることが判る。

DataFrame型の値の部分をndarray型に変換して出力して見るための次のコードを用意した。

 

print('data_csv.values =\n', data_csv.values)

 

実行すると、以下の出力を得る。

 

data_csv.values =

 [['太郎' 100.0 50 5.0]

 ['次郎' nan 30 3.0]

 ['花子' 120.0 70 nan]]

 

CSVファイルの空白セルが、nanになっていることが分かる。

セルの値がnanであるかどうかは、モジュールmathisnan関数で調べることができる。

次のスクリプトは、isnanの使用例である。

 

for v in data_csv[data_csv.keys()[1]]:

    print(f'{v}:', end='')

    ck = 'NAN' if math.isnan(v) else 'Not NAN'

    print(' ', ck)

 

実行すると、以下の出力を得る。

 

Key = 変数1

100.0:  Not NAN

nan:  NAN

120.0:  Not NAN

 

 

上の空白セルに関わる説明のスクリプトをまとめて、リスト2とした。

 

 

リスト2

 

import pandas as pd

import numpy as np

import math

 

data_csv = pd.read_csv('sample2.csv', encoding='shift-jis')

print('DataFrame =\n', data_csv)

print('Keys =\n', data_csv.keys())

for nm in data_csv.keys():

    print('Key =',nm)

    print(data_csv[nm])

 

print('data_csv.values =\n', data_csv.values)

 

for nm in data_csv.keys():

    print('Key = ',nm, ',  values =', data_csv[nm].values)

print()

print('Key =', data_csv.keys()[1])

for v in data_csv[data_csv.keys()[1]]:

    print(f'{v}:', end='')

    ck = 'NAN' if math.isnan(v) else 'Not NAN'

    print(' ', ck)

 

 

 

CSVファイルの書き出し

 

データはpandasDataFrame型の関数to_csvを用いて、CSVファイルとして保存できる。

次のスクリプトは、辞書型データraw_dataDataFrame型に変換して、CSVファイルdata1.csvに保存するものである。

 

raw_data = {'a':[1,2,3], 'b':[100,200,300]}

pd.DataFrame(raw_data).to_csv('data1.csv')

 

このスクリプトを実行すると、図4のCSVファイルdata1.csvが作成される。

 

図4

 

図4のCSVファイルでは、インデックスが自動的に作成されて第1列(A列)に表示されている。

このインデックスを挿入しないときは、関数to_csvの引数にindex=Falseを設定すればよい。

次のコード

 

pd.DataFrame(raw_data).to_csv('data2.csv', index=False)

 

で作成されたCSVファイルdata2.csvには、インデックスが無い(図5)。

 

図5

 

DataFrameの各keyの要素の数は同じでなければならないという制約がある。同じでないときは、numpy.nanを設定して、要素の数を揃えればよい。

次のスクリプトでは、辞書の各キーの値のリストの要素数をnumpy.nanを入れて3個に揃えている。

 

raw_data_ex = {'a':[1,2,3], 'b':[100,np.nan,200], 'c':[5,6,np.nan]}

pd.DataFrame(raw_data_ex).to_csv('data3.csv')

 

上のスクリプトの実行によって作成されたCSVファイルdata3.csvでは、numpy.nanの箇所は空白セルになっている(図6)。

 

図6

 

上の説明でのスクリプトは、リスト3としてまとめた。

 

 

リスト3

 

import pandas as pd

import numpy as np

 

raw_data = {'a':[1,2,3], 'b':[100,200,300]}

pd.DataFrame(raw_data).to_csv('data1.csv')

 

pd.DataFrame(raw_data).to_csv('data2.csv', index=False)

 

raw_data_ex = {'a':[1,2,3], 'b':[100,np.nan,200], 'c':[5,6,np.nan]}

pd.DataFrame(raw_data_ex).to_csv('data3.csv')

 

 

 

DataFrame型のオブジェクトは、配列から簡単に作ることができる。

次のスクリプトでは、配列aからDataFrameが作成されている。

 

a = [[1,2,3],[4,5,6]]

df_a = pd.DataFrame(a)

print(df_a)

 

実行すると、次の出力を得る。

 

   0  1  2

0  1  2  3

1  4  5  6

 

配列aが列単位にまとめられていることが分かる。列のkeyが0から2まで自動的に割り当てられ、行のindexが0か1まで自動的に割り当てられている。

行単位でまとめるために、配列andarray型に変換して転置行列を取る。

 

df_b = pd.DataFrame(np.array(a).T)

print(df_b)

 

実行すると次の出力を得る。

 

   0  1

0  1  4

1  2  5

2  3  6

 

列のkeyを自動的に割り当てられる0からの整数ではなく、引数culumnsで明示的に設定することもできる。

 

df_c = pd.DataFrame(np.array(a).T, columns=['Var_A', 'Var_B'])

print(df_c)

 

実行すると、次の出力を得る。

 

   Var_A  Var_B

0      1      4

1      2      5

2      3      6

 

上のスクリプトに続いて、次のスクリプトを実行してCSVファイルとする。

 

df_c.to_csv('data_c.csv', index=False)

 

実行後、図7に示すCSVファイルdata_c.csvが作成される。

 

図7

 

上の説明でのスクリプトファイルをリスト4にまとめた。

 

 

リスト4

 

import pandas as pd

import numpy as np

 

a = [[1,2,3],[4,5,6]]

df_a = pd.DataFrame(a)

print(df_a)

print()

df_b = pd.DataFrame(np.array(a).T)

print(df_b)

print()

df_c = pd.DataFrame(np.array(a).T, columns=['Var_A', 'Var_B'])

print(df_c)

df_c.to_csv('data_c.csv', index=False)

 

 

 

Home