2016-06-11 56 views
1

我有一個DataFrame列AB。現在我想產生列C這樣的:填充轉發條件結果

 A B C 
index 
1  0 50 NaN 
2  1 60 60 
3  0 40 60 
4  0 30 60 
5  1 40 40 

C獲得此行中,如果A==1的的B值。然後這個值保存在下一行,直到下一次A==1。我如何以矢量化的方式做到這一點?

回答

2

可以選擇B的值,其中A == 1,然後填充正向:

a = pd.DataFrame({"A":[0,1,0,0,1], "B":[50,60,40,30,40]}, index=[1,2,3,4,5]) 
a["C"] = a.B[a.A == 1] 
a = a.fillna(method="ffill") 

的ffill方法向前傳播的最後一個有效觀察填寫的NaN。有關更多信息,請參閱http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.fillna.html

這給出:

A B C 
1 0 50 NaN 
2 1 60 60 
3 0 40 60 
4 0 30 60 
5 1 40 40 
+0

沒錯,就是這樣,感謝@Seabass –

1

替代方法中,一襯墊,這似乎是位更快:

In [301]: df['C'] = pd.Series(np.where(df.A==1, df.B, np.nan), index=df.index).ffill() 

In [302]: df 
Out[302]: 
    A B  C 
1 0 50 NaN 
2 1 60 60.0 
3 0 40 60.0 
4 0 30 60.0 
5 1 40 40.0 

設置500K行DF:

In [310]: %paste 
def method1(a): 
    a["C"] = a.B[a.A == 1] 
    return a.fillna(method="ffill") 

def method2(df): 
    df['C'] = pd.Series(np.where(df.A==1, df.B, np.nan), index=df.index).ffill() 
    return df 
## -- End pasted text -- 

df = pd.concat([df] * 10**5, ignore_index=True) 

In [313]: df.shape 
Out[313]: (500000, 2) 

定時:

In [311]: %timeit method1(df) 
10 loops, best of 3: 95.3 ms per loop 

In [312]: %timeit method2(df) 
100 loops, best of 3: 17.8 ms per loop 

有趣,我認爲@海鱸魚的方法應該是快,但顯然這不是......

+0

絕對是最完美的解決方案,謝謝@MaxU –

+0

@Al_Iskander,歡迎您! :) – MaxU