2017-09-13 73 views
4
import pandas as pd 
import numpy as np 

pb = {"mark_up_id":{"0":"123","1":"456","2":"789","3":"111","4":"222"},"mark_up":{"0":1.2987,"1":1.5625,"2":1.3698,"3":1.3333,"4":1.4589}} 

data = {"id":{"0":"K69","1":"K70","2":"K71","3":"K72","4":"K73","5":"K74","6":"K75","7":"K79","8":"K86","9":"K100"},"cost":{"0":29.74,"1":9.42,"2":9.42,"3":9.42,"4":9.48,"5":9.48,"6":24.36,"7":5.16,"8":9.8,"9":3.28},"mark_up_id":{"0":"123","1":"456","2":"789","3":"111","4":"222","5":"333","6":"444","7":"555","8":"666","9":"777"}} 

pb = pd.DataFrame(data=pb).set_index('mark_up_id') 
df = pd.DataFrame(data=data) 

我知道我可以使用類似VLOOKUP針對與普通指數系列。我想把這個回報加起來,並用每個成本乘以一個通用指數來產生一個名爲價格的新列。大熊貓使用地圖

我知道我可以將兩者合併,然後運行計算。這就是我產生所需輸出的方式。我希望能夠做到這一點,類似於如何循環訪問字典,並使用鍵在另一個字典中查找值並在循環中執行某種計算。考慮到PANDAS數據框位於字典之上,必須有一種使用join/map/apply的組合來實現這一點,而無需實際將兩個數據集合在內存中。

所需的輸出:

desired_output = {"cost":{"0":29.74,"1":9.42,"2":9.42,"3":9.42,"4":9.48},"id":{"0":"K69","1":"K70","2":"K71","3":"K72","4":"K73"},"mark_up_id":{"0":"123","1":"456","2":"111","3":"123","4":"789"},"price":{"0":38.623338,"1":14.71875,"2":12.559686,"3":12.233754,"4":12.985704}} 
do = pd.DataFrame(data=desired_output) 

積分:

解釋接受的答案和...

pb.loc[df['mark_up_id']]['mark_up'] * df.set_index('mark_up_id')['cost'] 

,爲什麼我得到的上述下面的lambda函數的區別從命中錯誤...

df.apply(lambda x : x['cost']*pb.loc[x['mark_up_id']],axis=1) 

返回一個錯誤說:

KeyError: ('the label [333] is not in the [index]', u'occurred at index 5') 

回答

3

嘗試

df['price'] = df['mark_up_id'].map(pb['mark_up']) * df['cost'] 

你得到

cost id mark_up_id price 
0 29.74 K69 123   38.623338 
1 9.42 K70 456   14.718750 
2 9.42 K71 111   12.559686 
3 9.42 K72 123   12.233754 
4 9.48 K73 789   12.985704 
+0

只有在乘以兩個相同長度的序列對象時,這才起作用嗎?如果指標不同+一系列更長。 –

+1

地圖會將df中的mark_up_id值映射到pb中的str_price_band,並返回您按價格乘以相應的mark_up值。所以長度不必相同 – Vaishali

+0

如果你正在處理df中的mark_up_id,而pb中不存在mark_up_id,那麼顯然它將無法找到相應的mark_up並返回NaN。 – Vaishali

2

更新:更新的問題:

In [79]: df = df.assign(price=df['mark_up_id'].map(pb['mark_up']) * df['cost']).dropna() 

In [80]: df 
Out[80]: 
    cost id mark_up_id  price 
0 29.74 K69  123 38.623338 
1 9.42 K70  456 14.718750 
2 9.42 K71  789 12.903516 
3 9.42 K72  111 12.559686 
4 9.48 K73  222 13.830372 

老答案:

In [67]: df = df.assign(price=df['mark_up_id'].map(pb['mark_up']) * df['cost']) 

In [68]: df 
Out[68]: 
    cost id mark_up_id  price 
0 29.74 K69  123 38.623338 
1 9.42 K70  456 14.718750 
2 9.42 K71  111 12.559686 
3 9.42 K72  123 12.233754 
4 9.48 K73  789 12.985704 
+0

是否可以使用apply和lamba函數做到這一點? –

+0

@YaleNewman,是的,但它看起來很醜,而且會變慢......你爲什麼要這樣做? – MaxU

+0

試圖更好地理解基礎數據對象是如何工作的並且可以相互關聯 –

0
df['price'] = df['cost'] * df['mark_up_id'].map(pb['markup']) 

現在df將是您所需的輸出。

2

通過使用merge

df=df.merge(df1,left_on='mark_up_id',right_index=True) 
df.assign(price=df['cost'].mul(df['mark_up'])).drop('mark_up',1) 
Out[254]: 
    cost id mark_up_id  price 
0 29.74 K69  123 38.623338 
3 9.42 K72  123 12.233754 
1 9.42 K70  456 14.718750 
2 9.42 K71  111 12.559686 
4 9.48 K73  789 12.985704 

如果你想applylambda:它是醜.....真正的...

df.apply(lambda x : x['cost']*df1.loc[x['mark_up_id']],axis=1) 

更改爲(更難看.. .T_T)

df.apply(lambda x :x['cost']*df1.loc[x['mark_up_id']] if pd.Series(x['mark_up_id']).isin(df1.index)[0] else np.nan,axis=1)