兎の真似をする烏

全力で"楽"である為に・人生が"面白く"ある為に

pandasの使い方について

やりたいこと

PythonExcelファイル(.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()の方が柔軟性があると思われる。