比較、結合等の操作を行うやり方を忘れないうちにメモ。
エクセルで作ったファイル(csv形式)を読む為に文字コードの指定、
mergeを使って2つのファイルを外部結合、
内部データの比較方法、列の新規追加、
結合したデータをファイルに出力する方法を
簡単なユースケースを元に説明します。
公式サイトがhttps://pandas.pydata.org/pandas-docs/stable/にあるので、
さらに細かいものはそちらを参照ください。
ユースケース
担当者ごとの1日の売り上げデータをファイルに出力して、それを比較し、ノルマがクリアできているか確認する。
データは下記の通り2/1と2/2の2つのcsvファイルを用意。
上が2/1のデータ(sales_0201.csv)。下が2/2のデータ(sales_0202.csv)
グループID | ID | 売上 | お休み |
A | yamada | 1000 | |
B | yamada | 500 | |
A | satou | 200 | |
A | ikeda | 300 |
グループID | ID | 売上 | お休み |
A | yamada | 100 | |
B | yamada | 200 | |
A | satou | 0 | TRUE |
A | ikeda | 600 | |
B | 新人 |
サンプルソース
import pandas as pd before_pd = pd.read_csv('sales_0201.csv', encoding='shift_jis') after_pd = pd.read_csv('sales_0202.csv', encoding='shift_jis') f=pd.merge(before_pd, after_pd, on=['グループID', 'ID'], suffixes=['_0201', '_0202'], how='outer') f['is_ノルマクリア'] = ( (f['売上_0201'] < f['売上_0202']) | ((f['売上_0202'] == 0) & (f['お休み_0202'] == True)) | f['売上_0202'].isnull() ) f['売上合計'] = (f[['売上_0201','売上_0202']].sum(axis='columns')) f.to_csv('result.csv',index=False, encoding='shift_jis')
サンプル実行結果(result.csv)
グループID | ID | 売上_0201 | お休み_0201 | 売上_0202 | お休み_0202 | is_ノルマクリア | 売上合計 |
A | yamada | 1000 | 100 | FALSE | 1100 | ||
B | yamada | 500 | 200 | FALSE | 700 | ||
A | satou | 200 | 0 | TRUE | TRUE | 200 | |
A | ikeda | 300 | 600 | TRUE | 900 | ||
B | 新人 | TRUE | 0 |
ノルマクリアの確認として、前日より売り上げがあることを確認します。
ただし、お休みで売上0の人。新規登録されて売上データが無い人(新人)
は無条件ノルマクリアにします(列:is_ノルマクリア)。
売上合計は売り上げの合計値を設定します(列:売上合計)。
操作の説明
ファイルをエンコードする方法
before_pd = pd.read_csv('sales_0201.csv', encoding="shift_jis")
after_pd = pd.read_csv('sales_0202.csv', encoding="shift_jis")
のread_csvでファイルを読み込み、その属性に encoding を指定可能です。
エクセルは文字コード
shift_jis
なので、それを指定します。
2つのファイルを外部結合
f=pd.merge(before_pd, after_pd, on=['グループID', 'ID'], suffixes=['_0201', '_0202'], how='outer')
merge を利用して結合します。
DBの外部結合とほぼ同じ感覚で利用可能。
on=
でキーとなる列名を設定します。複数の場合はリストを利用します。⇒IDがyamadaでかぶっているので、グループIDも指定する必要有。
suffixes=
は列に追加される末尾文字です。how
はどのように結合するか結合方法を指定します。パターンは下記の通り。
内部結合(inner_join): how='inner'
左結合(left_join): how='left'
右結合(right_join): how='right'
外部結合(outer_join): how='outer'
結合したデータを判定し、列を追加
f['is_ノルマクリア'] = ( (f['売上_0201'] < f['売上_0202']) | ((f['売上_0202'] == 0) | (f['お休み_0202'] == True)) | f['売上_0202'].isnull() )f[列名]で列を指定し、比較式を記述することが可能。
比較は行単位で行われます。
上記では
(数値の比較 or (数値比較 and 文字列の比較) or データ無し)
の条件結果を列に追加しています。
and は
&
or は|
で指定。()でくくると判定を絞れるのはpythonの記述とかそのままです。
isnull()
でデータが存在しないデータかどうかを判定します。⇒f['売上_0202'] == Noneとかはできないので注意。
f['is_ノルマクリア'] =
の箇所で追加したい列名を記述します。
行単位の合計値の計算
f['売上合計'] = (f[['売上_0201','売上_0202']].sum(axis='columns'))
売上の列でそれぞれsuffixesで指定した文字列を加えて、
ファイル1、ファイル2にある値の合計値をsumで算出します。
f[['売上_0201','売上_0202']]
の箇所で列の指定、 axis='columns'
の箇所で行の計算が可能。ちなみに index と指定すると列の計算になります。ファイル出力
f.to_csv('result.csv',index=False, encoding='shift_jis')
to_csvでcsvファイル出力します。
pandasではファイル出力すると、行のindexを示す列を先頭に追加しますが、
index=False
を指定することによりそれを除外します。人が確認するデータの想定なので、今回は除外。
encoding は文字コードを指定し出力します。
コメント