Excelファイルの読み書き
Excelファイルの読み込み、書き出しは、ライブラリpandasを用いると簡単にできる。まず、読み込みについて説明する。その後、書き出しについて説明する。
図1に示すExcelファイルの読み込みを行う。
図1 Excelファイルsample1.xlsx
Excelファイルsample1.xlsxは、pandasの関数read_excelによって読み込むことができる。コードを次に示す。
data_xlsx = pandas.read_excel('sample1.xlsx')
Excelから読み込まれた内容は、pandasのDataFrame型として表される。DataFrame型は配列のようなものであり、列がExcelファイルの第1行目の値をキーとする辞書型の感覚で使えるが、便利な関数が用意されている。
読み込んだ内容を、次のprint関数
print('data_xlsx =\n', data_xlsx)
で出力すると以下のようになる。
data_xlsx =
ケース識別子 変数1 変数2 変数3
0 太郎 100 50 5
1 次郎 150 30 3
2 花子 120 70 7
第1列目には、0から始まるデータの通し番号(index)が出力されている。
第1行目は、Excelファイルの第1行目の値で、keyとして用いられる。
2行目以降、2列目より右側に、Excelデータの2行目以降が出力されている。
次のコードは、keyを出力するものである。
print('data_xlsx.keys() =\n', data_xlsx.keys())
実行すると、次の出力を得る。
data_xlsx.keys() =
Index(['ケース識別子', '変数1', '変数2', '変数3'], dtype='object')
各keyに対する値は、次のコードで確認できる。
for nm in data_xlsx.keys():
print('key =',nm)
print('data_xlsx[key]
=\n', data_xlsx[nm])
実行すると、以下の出力を得る。
key = ケース識別子
data_xlsx[key] =
0 太郎
1 次郎
2 花子
Name: ケース識別子, dtype: object
key = 変数1
data_xlsx[key] =
0 100
1 150
2 120
Name: 変数1, dtype: int64
key = 変数2
data_xlsx[key] =
0 50
1 30
2 70
Name: 変数2, dtype: int64
key = 変数3
data_xlsx[key] =
0 5
1 3
2 7
Name: 変数3, dtype: int64
アトリビュートvaluesを用いるとkeyに対する値がndarray型の配列として得られる。次のコードではvaluesによって配列型として値を得ている。
for nm in data_xlsx.keys():
print('key =',nm)
print('data_xlsx[key].values
\n', data_xlsx[nm].values)
実行すると、以下の出力を得る。
key = ケース識別子
data_xlsx[key].values
['太郎' '次郎' '花子']
key = 変数1
data_xlsx[key].values
[100 150 120]
key = 変数2
data_xlsx[key].values
[50 30 70]
key = 変数3
data_xlsx[key].values
[5 3 7]
data_xlsxに読み込まれた値全体のndarray型の値を得るときは、keyを指定せずにvaluesを適用すればよい。次のコード
print('data_xlsx.vales =\n', data_xlsx.values)
を実行すると、以下の出力を得る。
data_xlsx.vales =
[['太郎' 100 50 5]
['次郎' 150 30 3]
['花子' 120 70 7]]
ndarray型であるので、numpyの関数が利用できる。
次のコードは、Excelファイルの2列目以降の列ごとの和を求めるものである。
print(numpy.sum(data_xlsx.values.T[1:],
axis=1))
実行すると次の出力を得る。
[370 150 15]
以上のスクリプトを1つのスクリプトにリスト1としてまとめた。
リスト1
import pandas
import numpy
data_xlsx = pandas.read_excel('sample1.xlsx')
print('data_xlsx
=\n', data_xlsx)
print('data_xlsx.keys()
=\n', data_xlsx.keys())
print()
for nm in data_xlsx.keys():
print('key =',nm)
print('data_xlsx[key]
=\n', data_xlsx[nm])
print()
for nm in data_xlsx.keys():
print('key =',nm)
print('data_xlsx[key].values
\n', data_xlsx[nm].values)
print()
print('data_xlsx.vales
=\n', data_xlsx.values)
print()
print(numpy.sum(data_xlsx.values.T[1:], axis=1))
空白セルがある場合
Excelに空白のセルがある場合、空白のセルはNAN(Not a Number)に置き換えられる。
図2
図2のExcelファイルample2.xlsxでは、2つのセルが空白である。
このファイルを次のコードで読み込み、出力してみる。
data_xlsx = pd.read_excel('sample2.xlsx')
print('DataFrame
=\n', data_xlsx)
以下の出力を得る。
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_xlsx.values =\n', data_xlsx.values)
実行すると、以下の出力を得る。
data_xlsx.values =
[['太郎' 100.0 50 5.0]
['次郎' nan 30 3.0]
['花子' 120.0 70 nan]]
Excelファイルの空白セルが、nanになっていることが分かる。
セルの値がnanであるかどうかは、モジュールmathのisnan関数で調べることができる。
次のスクリプトは、isnanの使用例である。
for v in data_xlsx[data_xlsx.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_xlsx = pd.read_excel('sample2.xlsx')
print('DataFrame
=\n', data_xlsx)
print('Keys =\n', data_xlsx.keys())
for nm in data_xlsx.keys():
print('Key =',nm)
print(data_xlsx[nm])
print('data_xlsx.values
=\n', data_xlsx.values)
for nm in data_xlsx.keys():
print('Key = ',nm, ', values =', data_xlsx[nm].values)
print()
print('Key =', data_xlsx.keys()[1])
for v in data_xlsx[data_xlsx.keys()[1]]:
print(f'{v}:', end='')
ck
= 'NAN' if math.isnan(v) else 'Not NAN'
print(' ', ck)
データはpandasのDataFrame型の関数to_excelを用いて、Excelファイルとして保存できる。
次のスクリプトは、辞書型データraw_dataをDataFrame型に変換して、Excelファイルdata1.xlsxに保存するものである。
raw_data = {'a':[1,2,3], 'b':[100,200,300]}
pd.DataFrame(raw_data).to_excel('data1.xlsx')
このスクリプトを実行すると、図3のExcelファイルdata1.xlsxが作成される。
図3
図3のExcelファイルでは、インデックスが自動的に作成されて第1列(A列)に表示されている。
このインデックスを挿入しないときは、関数to_excelの引数にindex=Falseを設定すればよい。
次のコード
pd.DataFrame(raw_data).to_excel('data2.xlsx', index=False)
で作成されたExcelファイルdata2.xlsxには、インデックスが無い(図4)。
図4
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_excel('data3.xlsx')
上のスクリプトの実行によって作成されたExcelファイルdata3.xlsxでは、numpy.nanの箇所は空白セルになっている(図5)。
図5
上の説明でのスクリプトは、リスト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_excel('data1.xlsx')
pd.DataFrame(raw_data).to_excel('data2.xlsx', 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_excel('data3.xlsx')
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まで自動的に割り当てられている。
行単位でまとめるために、配列aをndarray型に変換して転置行列を取る。
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
上のスクリプトに続いて、次のスクリプトを実行してExcelファイルとする。
df_c.to_excel('data_c.xlsx', index=False)
実行後、図6に示すExcelファイルdata_c.xlsxが作成される。
図6
上の説明でのスクリプトファイルをリスト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_excel('data_c.xlsx', index=False)