2015-07-10 102 views
2

我有大量的觀測值DataFrame。即從值表中爲觀察值賦值

value 1,value 2 
a,1 
a,1 
a,2 
b,3 
a,3 

我現在值

_ ,a,b 
1 ,10,20 
2 ,30,40 
3 ,50,60 

什麼將是一個有效的方式的外部數據幀從索引表添加到數據框第一的價值觀?即:

value 1,value 2, new value 
a,1,10 
a,1,10 
a,2,30 
b,3,60 
a,3,50 
+0

DF代表什麼? –

+0

DF代表DataFrame – DeanLa

回答

4

另一種解決方案使用.lookup()。這只是一條線,矢量化的解決方案。適合大型數據集。

import pandas as pd 
import numpy as np 

# generate some artificial data 
# ================================ 
np.random.seed(0) 
df1 = pd.DataFrame(dict(value1=np.random.choice('a b'.split(), 10), value2=np.random.randint(1, 10, 10))) 

df2 = pd.DataFrame(dict(a=np.random.randn(10), b=np.random.randn(10)), columns=['a', 'b'], index=np.arange(1, 11)) 

df1 

Out[178]: 
    value1 value2 
0  a  6 
1  b  3 
2  b  5 
3  a  8 
4  b  7 
5  b  9 
6  b  9 
7  b  2 
8  b  7 
9  b  8 


df2 

Out[179]: 
     a  b 
1 2.5452 0.0334 
2 1.0808 0.6806 
3 0.4843 -1.5635 
4 0.5791 -0.5667 
5 -0.1816 -0.2421 
6 1.4102 1.5144 
7 -0.3745 -0.3331 
8 0.2752 0.0474 
9 -0.9608 1.4627 
10 0.3769 1.5350 



# processing: one liner lookup function 
# ======================================================= 
# df1.value2 is the index and df1.value1 is the column 
df1['new_values'] = df2.lookup(df1.value2, df1.value1) 

Out[181]: 
    value1 value2 new_values 
0  a  6  1.4102 
1  b  3  -1.5635 
2  b  5  -0.2421 
3  a  8  0.2752 
4  b  7  -0.3331 
5  b  9  1.4627 
6  b  9  1.4627 
7  b  2  0.6806 
8  b  7  -0.3331 
9  b  8  0.0474 
+0

當索引爲0時,您不需要將索引值偏移1嗎? – EdChum

+0

@EdChum這絕對是一個有效的點,並且在構建數據「df2」時已經完成。因爲我們只是使用列值,因此'df1'中的索引無關緊要。 –

+0

目前還不清楚''_''是一個實際的列還是來自OP的樣本dfs的索引,但是'lookup'是更好的方法+1 – EdChum

1

假設你的第一和第二DFS分別爲dfdf1,您可以合併的匹配列,然後掩蓋的「a」和「b」條件:

In [9]: 
df = df.merge(df1, left_on=['value 2'], right_on=['_']) 
a_mask = (df['value 2'] == df['_']) & (df['value 1'] == 'a') 
b_mask = (df['value 2'] == df['_']) & (df['value 1'] == 'b') 
df.loc[a_mask, 'new value'] = df['a'].where(a_mask) 
df.loc[b_mask, 'new value'] = df['b'].where(b_mask) 
df 

Out[9]: 
    value 1 value 2 _ a b new value 
0  a  1 1 10 20   10 
1  a  1 1 10 20   10 
2  a  2 2 30 40   30 
3  b  3 3 50 60   60 
4  a  3 3 50 60   50 

可以然後刪除附加列:

In [11]: 
df = df.drop(['_','a','b'], axis=1) 
df 

Out[11]: 
    value 1 value 2 new value 
0  a  1   10 
1  a  1   10 
2  a  2   30 
3  b  3   60 
4  a  3   50 

的另一種方式是定義一個FUNC執行查閱:

In [15]: 
def func(x): 
    row = df1[(df1['_'] == x['value 2'])] 
    return row[x['value 1']].values[0] 

df['new value'] = df.apply(lambda x: func(x), axis = 1) 
df 

Out[15]: 
    value 1 value 2 new value 
0  a  1   10 
1  a  1   10 
2  a  2   30 
3  b  3   60 
4  a  3   50 

編輯

使用@Jianxun李的lookup的作品,但你必須以抵消指數作爲指數是基於0

In [20]: 
df['new value'] = df1.lookup(df['value 2'] - 1, df['value 1']) 
df 

Out[20]: 
    value 1 value 2 new value 
0  a  1   10 
1  a  1   10 
2  a  2   30 
3  b  3   60 
4  a  3   50