概要
以前
Python pandasで正規化されたcsvをjoinして確認しやすく加工
という記事を紹介した。
いざ、実務的に使うにあたって、
以下のようなデータにぶちあたり、結構ハマったので
投稿しておきます。
きっともっとスマートな方法があるかとは思いますが
一旦目的は達っせられたので。
以下のような2つのデータがあるとする。
それぞれに
メインキー(必須)
サブキー(任意)
がある。
トランザクションのデータは、Excel形式で、サブキーの省略は、" " 一定のスペースがある。
マスタのデータは、CSV形式で、サブキーの省略は、"" スペース無しで格納されている。
RDBMSなりに格納して、trim 付でジョインすれば一発なのだが
Python単体での実現
利用環境
>
Python 3.8.2
Visual Studio Code 1.45.0
>
ソースコード
以下のように、ジョインして最終的には確認用のExcelを出力している
#メインキー(必須)とサブキー(任意)をジョインする。
import pandas as pd
import re
def main():
#本体処理
#データを読み込み
new_acc_master = pd.read_csv(".\\subkey_join\\マスタ.csv",encoding="cp932", dtype=str)
value_trn = pd.read_excel(".\\subkey_join\\トランザクション.xlsx", dtype=str)
#サブ値無し削除
value_trn['サブコード'] = value_trn['サブコード'].str.strip()
new_acc_master['サブコード'] = new_acc_master['サブコード'].str.strip()
#トランの、サブ完全値無しを、値無しに置き換え 元が 空白があるデータは、これでOKだった。
value_trn.サブコード[value_trn.サブコード == ""] = "値無し"
print(type(value_trn))
print(value_trn.dtypes)
#☆☆ NG マスタ側も同じようにしようとしたが、下記ロジックでは変更されない
#new_acc_masternew_acc_master.サブ[new_acc_master.サブ == ""] = "値無し"
#マスタの、サブ値無し削除サブコード
#new_acc_master = new_acc_master.replace('^$',{'サブコード':'値無し'},regex=True)
print(new_acc_master['サブコード'].dtype)
#Python の文字型を指定して、astype
#pandas 上の型は、object で変わらないが、値無しのところは、"nan" に変わる
new_acc_master['サブコード'] = new_acc_master['サブコード'].astype(str)
print(new_acc_master['サブコード'].dtype)
##☆☆ これでOK もっとスマートな方法があるとは思うが。。
new_acc_master.サブコード[new_acc_master.サブコード == "nan"] = "値無し"
print(type(new_acc_master))
print(new_acc_master.dtypes)
#メインキー、サブキーでレフトジョインする。
jpin_pd = pd.merge(value_trn, new_acc_master, how="left", left_on=['メインコード','サブコード'], right_on=['メインコード','サブコード'],suffixes=('_trn','_new'))
#Excel出力
jpin_pd.to_excel(".\\subkey_join\\view_data.xlsx")
if __name__ == '__main__': main()