pandasの使い方について
やりたいこと
PythonでExcelファイル(.xls, .xlsx)の情報を読み込みたい。
ライブラリ
pandas
というライブラリを使用する。
pandasは標準ライブラリでは無いため、pipからインストールする。
また、Excelファイルを読み込む場合はxlrd
というライブラリも使用するので、こちらもpipからインストールする。
Excelデータ例
sample.xlsx
に以下のような内容のデータが記載されている。
pandasを利用してこのデータを読み込んでみる。
日付 | 科目 | 入金 | 出金 | 摘要 | 残高 |
---|---|---|---|---|---|
2020/10/01 | 売掛金 | 15,000 | A商店 | 15,000 | |
2020/10/02 | 売上 | 500,000 | B会社 | 515,000 | |
2020/10/03 | 買掛金 | 230,000 | C会社 | 285,000 | |
2020/10/04 | 売上 | 800,000 | E会社 | 1,085,000 | |
2020/10/05 | 消耗品費 | 47,000 | D | 1,038,000 | |
2020/10/06 | 雑費 | 7,000 | E | 1,031,000 | |
2020/10/07 | 未収入金 | 423,000 | F商事 | 1,454,000 | |
2020/10/08 | 普通預金 | 1,000,000 | G銀行 | 454,000 | |
2020/10/09 | 未払金 | 50,000 | H商店 | 404,000 | |
2020/10/10 | 立替金 | 10,000 | I商店 | 414,000 |
読み込み
単純にExcelファイルを読み込ませてみる
import pandas def read_excel(): excel_file_path = './sample.xlsx' data = pandas.read_excel(excel_file_path) print(data) if __name__ == '__main__': read_excel()
結果は以下の通り。
日付 科目 入金 出金 摘要 残高 0 2020-10-01 売掛金 15000.0 NaN A商店 15000 1 2020-10-02 売上 500000.0 NaN B会社 515000 2 2020-10-03 買掛金 NaN 230000.0 C会社 285000 3 2020-10-04 売上 800000.0 NaN E会社 1085000 4 2020-10-05 消耗品費 NaN 47000.0 D 1038000 5 2020-10-06 雑費 NaN 7000.0 E 1031000 6 2020-10-07 未収入金 423000.0 NaN F商事 1454000 7 2020-10-08 普通預金 NaN 1000000.0 G銀行 454000 8 2020-10-09 未払金 NaN 50000.0 H商店 404000 9 2020-10-10 立替金 10000.0 NaN I商店 414000
注意
読み込むExcelファイルを他で開いているとエラーが発生する。
index指定
index_col
オプションを指定することでindexを指定することができる。
先の例ではindex_colの指定が無いため、一番左に記載されている番号(自動採番)がindexとして取り扱われている。
例えば、日付をindexにしたい場合はindex_col=0
もしくはindex_col='日付'
と指定する。
import pandas def read_excel(): excel_file_path = './sample.xlsx' data = pandas.read_excel(excel_file_path, index_col=0) print(data) if __name__ == '__main__': read_excel()
結果は以下の通り。
科目 入金 出金 摘要 残高 日付 2020-10-01 売掛金 15000.0 NaN A商店 15000 2020-10-02 売上 500000.0 NaN B会社 515000 2020-10-03 買掛金 NaN 230000.0 C会社 285000 2020-10-04 売上 800000.0 NaN E会社 1085000 2020-10-05 消耗品費 NaN 47000.0 D 1038000 2020-10-06 雑費 NaN 7000.0 E 1031000 2020-10-07 未収入金 423000.0 NaN F商事 1454000 2020-10-08 普通預金 NaN 1000000.0 G銀行 454000 2020-10-09 未払金 NaN 50000.0 H商店 404000 2020-10-10 立替金 10000.0 NaN I商店 414000
シートの読み込みについて
Excelファイルに複数シートが存在する場合、全部のシートを一括して読み込むことも、指定したシートのみを読み込むこともできる。
シートの指定にはsheet_name
オプションを使用することで実現できる。
このオプションを指定しなかった場合は、最初のシートの情報だけが読み込まれる。
全部のシートを読み込む
sheet_name=None
と指定する。
data = pandas.read_excel(excel_file_path, sheet_name=None)
指定したシートを読み込む
例えば、Excelファイルに「sheet1」「sheet2」「sheet3」の3つのシートが存在すると仮定する。
このとき、sheet2の情報を読み込みたい場合はsheet_name='sheet2'
と指定する。
data = pandas.read_excel(excel_file_path, sheet_name='sheet2')
また、sheet1とsheet3の2シートを読み込みたい場合はsheet_name=['sheet1', 'sheet3']
と指定する。
data = pandas.read_excel(excel_file_path, sheet_name=['sheet1', 'sheet3'])
シート番号を指定して読み込む
sheet_nameにはシート番号を指定して読み込むこともできる。
シート番号は0番からスタートする。
例えば、Excelファイルに「sheet1」「sheet2」「sheet3」の3つのシートが存在すると仮定する。
このとき、sheet2の情報を読み込みたい場合はsheet_name=1
と指定する。
data = pandas.read_excel(excel_file_path, sheet_name=1)
また、sheet1とsheet3の2シートを読み込みたい場合において、シート番号とシート名の両方を混在して指定することもできる。
つまりsheet_name=[0, 'sheet3']
のような指定が可能
data = pandas.read_excel(excel_file_path, sheet_name=[0, 'sheet3'])
データ取得
pandas.Series
→ 一次元データ
pandas.DataFrame
→ 二次元データ
列
pandas.Series - 単独列
[]
に列名を一つ指定する。
import pandas def read_excel(): excel_file_path = './sample.xlsx' data = pandas.read_excel(excel_file_path) print(data['日付']) if __name__ == '__main__': read_excel()
結果
0 2020-10-01 1 2020-10-02 2 2020-10-03 3 2020-10-04 4 2020-10-05 5 2020-10-06 6 2020-10-07 7 2020-10-08 8 2020-10-09 9 2020-10-10 Name: 日付, dtype: datetime64[ns]
attribute(属性)のように.
に続いて列名を指定することもできる。
ただし、既存のメソッド名が有る場合はそちらが優先されるので注意。
pandas.DataFrame - 単独列
[[]]
のようにして列名を一つ指定する。
import pandas def read_excel(): excel_file_path = './sample.xlsx' data = pandas.read_excel(excel_file_path) print(data[['日付']]) if __name__ == '__main__': read_excel()
結果
日付 0 2020-10-01 1 2020-10-02 2 2020-10-03 3 2020-10-04 4 2020-10-05 5 2020-10-06 6 2020-10-07 7 2020-10-08 8 2020-10-09 9 2020-10-10
pandas.DataFrame - 複数列
[[]]
にて複数の列を指定する。
import pandas def read_excel(): excel_file_path = './sample.xlsx' data = pandas.read_excel(excel_file_path) print(data[['日付', '残高']]) if __name__ == '__main__': read_excel()
結果
日付 残高 0 2020-10-01 15000 1 2020-10-02 515000 2 2020-10-03 285000 3 2020-10-04 1085000 4 2020-10-05 1038000 5 2020-10-06 1031000 6 2020-10-07 1454000 7 2020-10-08 454000 8 2020-10-09 404000 9 2020-10-10 414000
スライスで指定した場合(例:data[['日付':'残高']]
)、空のpanas.DataFrameが返却される。
loc
を利用すると列のスライスも可能であるらしい。詳細は省略。
行
pandas.DataFrame - 単独行
[]
にスライスを指定する。
例えば、最初の一行目だけを出力する場合は0:1
のように指定したら良い。
import pandas def read_excel(): excel_file_path = './sample.xlsx' data = pandas.read_excel(excel_file_path) print(data[0:1]) if __name__ == '__main__': read_excel()
結果
日付 科目 入金 出金 摘要 残高 0 2020-10-01 売掛金 15000.0 NaN A商店 15000
注意点としてはあくまでもスライスで指定する必要があるということ。
例えばdata[0]
のように指定してもエラーとなる。
pandas.DataFrame - 複数行
[]
にスライスを指定する。
例えば、一行目から五行目までを出力する場合は0:5
のように指定する。
import pandas def read_excel(): excel_file_path = './sample.xlsx' data = pandas.read_excel(excel_file_path) print(data[0:5]) if __name__ == '__main__': read_excel()
結果
日付 科目 入金 出金 摘要 残高 0 2020-10-01 売掛金 15000.0 NaN A商店 15000 1 2020-10-02 売上 500000.0 NaN B会社 515000 2 2020-10-03 買掛金 NaN 230000.0 C会社 285000 3 2020-10-04 売上 800000.0 NaN E会社 1085000 4 2020-10-05 消耗品費 NaN 47000.0 D 1038000
スライスで指定するのでstart:stop:step
のように指定することもできる。
例えば、一行目から五行目までを1つ飛ばしでデータを取得したい場合は0:5:2
のように指定する。
import pandas def read_excel(): excel_file_path = './sample.xlsx' data = pandas.read_excel(excel_file_path) print(data[0:5:2]) if __name__ == '__main__': read_excel()
結果
日付 科目 入金 出金 摘要 残高 0 2020-10-01 売掛金 15000.0 NaN A商店 15000 2 2020-10-03 買掛金 NaN 230000.0 C会社 285000 4 2020-10-05 消耗品費 NaN 47000.0 D 1038000
一行ずつ取り出す
iterrows()を使用
各行をインデックス名とデータのタプルで取得できる。
カラム名の指定や、列番号を指定して特定の値を取得できる。
import pandas def read_excel(): excel_file_path = './sample.xlsx' data = pandas.read_excel(excel_file_path) for index, row in data.iterrows(): print('INDEX : {}'.format(index)) print('----- DATA -----\n{}'.format(row)) print('----- 列番号指定 -----\n{}'.format(row[1])) print('----- 摘要抽出 -----\n{}'.format(row['摘要'])) print('========================================') if __name__ == '__main__': read_excel()
結果
INDEX : 0 ----- DATA ----- 日付 2020-10-01 00:00:00 科目 売掛金 入金 15000 出金 NaN 摘要 A商店 残高 15000 Name: 0, dtype: object ----- 列番号指定 ----- 売掛金 ----- 摘要抽出 ----- A商店 ======================================== INDEX : 1 ----- DATA ----- 日付 2020-10-02 00:00:00 科目 売上 入金 500000 出金 NaN 摘要 B会社 残高 515000 Name: 1, dtype: object ----- 列番号指定 ----- 売上 ----- 摘要抽出 ----- B会社 ======================================== INDEX : 2 ----- DATA ----- 日付 2020-10-03 00:00:00 科目 買掛金 入金 NaN 出金 230000 摘要 C会社 残高 285000 Name: 2, dtype: object ----- 列番号指定 ----- 買掛金 ----- 摘要抽出 ----- C会社 ======================================== INDEX : 3 ----- DATA ----- 日付 2020-10-04 00:00:00 科目 売上 入金 800000 出金 NaN 摘要 E会社 残高 1085000 Name: 3, dtype: object ----- 列番号指定 ----- 売上 ----- 摘要抽出 ----- E会社 ======================================== INDEX : 4 ----- DATA ----- 日付 2020-10-05 00:00:00 科目 消耗品費 入金 NaN 出金 47000 摘要 D 残高 1038000 Name: 4, dtype: object ----- 列番号指定 ----- 消耗品費 ----- 摘要抽出 ----- D ======================================== INDEX : 5 ----- DATA ----- 日付 2020-10-06 00:00:00 科目 雑費 入金 NaN 出金 7000 摘要 E 残高 1031000 Name: 5, dtype: object ----- 列番号指定 ----- 雑費 ----- 摘要抽出 ----- E ======================================== INDEX : 6 ----- DATA ----- 日付 2020-10-07 00:00:00 科目 未収入金 入金 423000 出金 NaN 摘要 F商事 残高 1454000 Name: 6, dtype: object ----- 列番号指定 ----- 未収入金 ----- 摘要抽出 ----- F商事 ======================================== INDEX : 7 ----- DATA ----- 日付 2020-10-08 00:00:00 科目 普通預金 入金 NaN 出金 1e+06 摘要 G銀行 残高 454000 Name: 7, dtype: object ----- 列番号指定 ----- 普通預金 ----- 摘要抽出 ----- G銀行 ======================================== INDEX : 8 ----- DATA ----- 日付 2020-10-09 00:00:00 科目 未払金 入金 NaN 出金 50000 摘要 H商店 残高 404000 Name: 8, dtype: object ----- 列番号指定 ----- 未払金 ----- 摘要抽出 ----- H商店 ======================================== INDEX : 9 ----- DATA ----- 日付 2020-10-10 00:00:00 科目 立替金 入金 10000 出金 NaN 摘要 I商店 残高 414000 Name: 9, dtype: object ----- 列番号指定 ----- 立替金 ----- 摘要抽出 ----- I商店 ========================================
後述するitertuples()
よりも速度が遅い。
ただし、こちらの方が柔軟にデータを取得することができる。
itertuples()を使用
デフォルトではPandas
という名前のnamedtuple
が返却される。
[]
で列番号を指定したり、.
で列名を指定することで値を取得できる。
(列名を日本語にしているので、この度は[]
でのデータの取得を考える)
import pandas def read_excel(): excel_file_path = './sample.xlsx' data = pandas.read_excel(excel_file_path) for row in data.itertuples(): print('----- DATA -----\n{}'.format(row)) print('----- 列番号指定 -----\n{}'.format(row[1])) print('========================================') if __name__ == '__main__': read_excel()
結果
----- DATA ----- Pandas(Index=0, 日付=Timestamp('2020-10-01 00:00:00'), 科目='売掛金', 入金=15000.0, 出金=nan, 摘要='A商店', 残高=15000) ----- 列番号指定 ----- 2020-10-01 00:00:00 ======================================== ----- DATA ----- Pandas(Index=1, 日付=Timestamp('2020-10-02 00:00:00'), 科目='売上', 入金=500000.0, 出金=nan, 摘要='B会社', 残高=515000) ----- 列番号指定 ----- 2020-10-02 00:00:00 ======================================== ----- DATA ----- Pandas(Index=2, 日付=Timestamp('2020-10-03 00:00:00'), 科目='買掛金', 入金=nan, 出金=230000.0, 摘要='C会社', 残高=285000) ----- 列番号指定 ----- 2020-10-03 00:00:00 ======================================== ----- DATA ----- Pandas(Index=3, 日付=Timestamp('2020-10-04 00:00:00'), 科目='売上', 入金=800000.0, 出金=nan, 摘要='E会社', 残高=1085000) ----- 列番号指定 ----- 2020-10-04 00:00:00 ======================================== ----- DATA ----- Pandas(Index=4, 日付=Timestamp('2020-10-05 00:00:00'), 科目='消耗品費', 入金=nan, 出金=47000.0, 摘要='D', 残高=1038000) ----- 列番号指定 ----- 2020-10-05 00:00:00 ======================================== ----- DATA ----- Pandas(Index=5, 日付=Timestamp('2020-10-06 00:00:00'), 科目='雑費', 入金=nan, 出金=7000.0, 摘要='E', 残高=1031000) ----- 列番号指定 ----- 2020-10-06 00:00:00 ======================================== ----- DATA ----- Pandas(Index=6, 日付=Timestamp('2020-10-07 00:00:00'), 科目='未収入金', 入金=423000.0, 出金=nan, 摘要='F商事', 残高=1454000) ----- 列番号指定 ----- 2020-10-07 00:00:00 ======================================== ----- DATA ----- Pandas(Index=7, 日付=Timestamp('2020-10-08 00:00:00'), 科目='普通預金', 入金=nan, 出金=1000000.0, 摘要='G銀行', 残高=454000) ----- 列番号指定 ----- 2020-10-08 00:00:00 ======================================== ----- DATA ----- Pandas(Index=8, 日付=Timestamp('2020-10-09 00:00:00'), 科目='未払金', 入金=nan, 出金=50000.0, 摘要='H商店', 残高=404000) ----- 列番号指定 ----- 2020-10-09 00:00:00 ======================================== ----- DATA ----- Pandas(Index=9, 日付=Timestamp('2020-10-10 00:00:00'), 科目='立替金', 入金=10000.0, 出金=nan, 摘要='I商店', 残高=414000) ----- 列番号指定 ----- 2020-10-10 00:00:00 ========================================
先述したiterrows()
よりも高速で処理することができる。
ただし、データの取得はiterrows()の方が柔軟性があると思われる。