概要
1レコードに複数(MAX:10)存在する類似データを、その類似データ毎のレコードとして新たに生成し、ローカルファイルに保存する Python プログラムです。(イメージは以下、、、、)
## 元データ
3001,WS1,中野 一郎,79,1630000,WS2,上野 二郎,104,1000000,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2021/7/27,
3002,PS1,下野 三郎,32,800000,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2021/6/29,
3003,ST1,中川 四郎,100,1656000,ST2,前川 五郎,64,1104000,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2021/8/30,
↓↓↓
## 抽出変換データ
3001,WS1,中野 一郎,79,1630000,2021/7/27
3001,WS2,上野 二郎,104,1000000,2021/7/27
3002,PS1,下野 三郎,32,800000,2021/6/29
3003,ST1,中川 四郎,100,1656000,2021/8/30
3003,ST2,前川 五郎,64,1104000,2021/8/30
実行環境
macOS Big Sur 11.1
python 3.8.3
実行プログラム
SE_Cost_1.py
import time
import json
import argparse
from tabulate import tabulate
from datetime import datetime
import pandas as pd
# 1レコードに存在する複数分の類似データをその類似毎のレコードとして新たに生成
def DataSpilit():
# csv型式のデータファイルをDataFrameとして読取る
df = pd.read_csv(filepath_or_buffer="./Operation_SE_Cost01.csv", encoding="ms932", sep=",")
# データの「NaN」値判断(True or False)のための変換
df1 = df.notnull()
# 類似データあたりの登録項目数
n = 4
# 取得コストの キーと値
row_key = ['Snum', 'Dept', 'J_Name', 'W_Time', 'UP_Cost', 'Fix_Date']
row_value = []
# 計上データの登録件数分の処理
for i in range(df.shape[0]) :
# 作業完了日が記入済み?
if df1.iloc[i, 41] :
# MAX10名のSEでの対応
se = []
for j in range(1,11) :
# 配分済みSEのみ対象でデータ生成
se.clear()
if df1.iloc[i, j*n] and df1.iloc[i, (j*n)-1] :
se.append([df.iloc[i, 0], df.iloc[i, (j*n)-3], df.iloc[i, (j*n)-2], df.iloc[i, (j*n)-1], int(df.iloc[i, j*n]), df.iloc[i, 41]])
row_value.extend(se)
# json形式への変換
rows = [dict(zip(row_key,item)) for item in row_value]
print(tabulate(rows, headers='keys'))
# ローカルファイルへの保存
cnt = DataToLocalFile(rows, row_key)
return i+1, cnt
# 編集データのローカルファイルへの保存
def DataToLocalFile(rows, row_key):
# データを DataFrame化
dfl=pd.DataFrame(rows)
print('\nDataFrameの各列のデータ型を確認 :\n', dfl.dtypes)
# DataFrameの各列のデータ型をobject型に変換
# (object型でないと Jsonファイルで保存できない)
dfl=dfl.astype(({"Snum": object}))
dfl=dfl.astype(({"W_Time": object}))
dfl=dfl.astype(({"UP_Cost": object}))
print('\nDataFrameの各列のデータ型を確認 :\n', dfl.dtypes)
# json形式へ再変換
rows = [dict(zip(row_key,item)) for item in dfl.values]
# 保存するファイル名の生成
now = datetime.now()
filename = './output/SESpilitCost_' + now.strftime('%Y%m%d_%H%M%S') + '.json'
print(filename)
# json.dump関数でファイルに書き込む
fw = open(filename,'w')
json.dump(rows, fw, indent=4)
fw.close()
return dfl.shape[0]
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='1レコードに存在する複数分の類似データをその類似毎のレコードとして新たに生成し、ローカルファイルに保存')
args = parser.parse_args()
start = time.time()
cnt0, cnt1 = DataSpilit()
generate_time = time.time() - start
print("")
print(" 元データ件数 : " + str(cnt0))
print(" 新データ件数 : " + str(cnt1))
print(" 取得時間:{0}".format(generate_time) + " [sec] \n")
プログラムの実行
## 実行状況
$ python SE_Cost_1.py
Snum Dept J_Name W_Time UP_Cost Fix_Date
------ ------ -------------- -------- --------- ----------
3001 WS1 中野 一郎 79 1630000 2021/7/27
3001 WS2 上野 二郎 104 1000000 2021/7/27
3002 PS1 下野 三郎 32 800000 2021/6/29
3003 ST1 中川 四郎 100 1656000 2021/8/30
3003 ST2 前川 五郎 64 1104000 2021/8/30
:
省略
:
DataFrameの各列のデータ型を確認 :
Snum int64
Dept object
J_Name object
W_Time float64
UP_Cost int64
Fix_Date object
dtype: object
DataFrameの各列のデータ型を確認 :
Snum object
Dept object
J_Name object
W_Time object
UP_Cost object
Fix_Date object
dtype: object
./output/SESpilitCost_20211112_142646.json
元データ件数 : 255
新データ件数 : 324
取得時間:0.06269383430480957 [sec]
## 実行結果
$ tree -a ./output
./output
└── SESpilitCost_20211112_142646.json
0 directories, 1 files
## jsonファイル(SESpilitCost_20211112_142646.json)の中身
[
{
"Snum": 3001,
"Dept": "WS1",
"J_Name": "中野 一郎",
"W_Time": 79.0,
"UP_Cost": 1630000,
"Fix_Date": "2021/7/27"
},
{
"Snum": 3001,
"Dept": "WS2",
"J_Name": "上野 二郎",
"W_Time": 104.0,
"UP_Cost": 1000000,
"Fix_Date": "2021/7/27"
},
{
"Snum": 3002,
"Dept": "PS1",
"J_Name": "下野 三郎",
"W_Time": 32.0,
"UP_Cost": 800000,
"Fix_Date": "2021/6/29"
},
{
"Snum": 3003,
"Dept": "ST1",
"J_Name": "中川 四郎",
"W_Time": 100.0,
"UP_Cost": 1656000,
"Fix_Date": "2021/8/30"
},
{
"Snum": 3003,
"Dept": "ST2",
"J_Name": "前川 五郎",
"W_Time": 64.0,
"UP_Cost": 1104000,
"Fix_Date": "2021/8/30"
},
:
:
省略
:
]
まとめ
この方法がベターかどうか自信はないですが、とりあえずやりたいことができているので OK かなぁ、、、、