Python プログラミング

Python pandas でメインキー(必須)、サブキー(任意)があるデータのジョイン

概要

以前
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()

-Python, プログラミング
-,