pandasで関数に複数の列の値を渡して返り値を列に追加する方法が分からなかったので調べてメモ。
ついでにDataFrameに列を追加する方法も。
test.csv
id | x | fix |
---|---|---|
1 | 2000 | 8 |
2 | 1500 | 4 |
3 | 3000 | 5 |
4 | 1000 | 15 |
test.py
import pandas as pd
def calc(dicModel, x, size, fix, modelName):
ret = 0
if x < dicModel[modelName]['Dx0']:
ret = dicModel[modelName]['Dy0']
elif x < dicModel[modelName]['Dx1']:
ret = (dicModel[modelName]['Dy1']-dicModel[modelName]['Dy0'])/ \
(dicModel[modelName]['Dx1']-dicModel[modelName]['Dx0'])* \
(x-dicModel[modelName]['Dx0']) + dicModel[modelName]['Dy0']
else:
ret = dicModel[modelName]['Dy1']
if size > 10:
ret += 5
if fix >= 8:
ret += 1
return ret
#モデルの情報の辞書
dicModel = {'modelA':{'size':9.8, 'Dx0':1000, 'Dy0':-1.0, 'Dx1':3000, 'Dy1':5.1, }, \
'modelB':{'size':13.3, 'Dx0':500, 'Dy0':0, 'Dx1':4000, 'Dy1':4.1, }}
#IDとモデル名の辞書
dicId = {1:'modelA', 2:'modelB', 3:'modelB', 4:'modelA'}
#読み込み
df = pd.read_csv('./test.csv')
#モデル名とサイズの辞書を作成
dicSize = {}
for amodel, ainfo in dicModel.items():
dicSize[amodel] = ainfo['size']
#dfにIDを基にしたモデル名の列を追加
df['modelName'] = df['id'].map(dicId)
#dfにモデル名を基にしたサイズの列を追加
df['size'] = df['modelName'].map(dicSize)
#dfに複数列を引数とした関数の返り値の列を追加
df['calc'] = df.apply(lambda x: calc(dicModel, x['x'], x['size'], x['fix'], x['modelName']), axis=1)
結果
id | x | fix | modelName | size | calc |
---|---|---|---|---|---|
1 | 2000 | 8 | modelA | 9.8 | 3.050000 |
2 | 1500 | 4 | modelB | 13.3 | 6.171429 |
3 | 3000 | 5 | modelA | 13.3 | 7.928571 |
4 | 1000 | 15 | modelA | 9.8 | 0.000000 |
検算
>> print(calc(dicModel=dicModel, x=1500, size=10, fix=4, modelName='modelB'))
6.171428571428571