我有一個DataFrame列A
和B
。現在我想產生列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
。我如何以矢量化的方式做到這一點?
我有一個DataFrame列A
和B
。現在我想產生列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
。我如何以矢量化的方式做到這一點?
可以選擇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
替代方法中,一襯墊,這似乎是位更快:
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
有趣,我認爲@海鱸魚的方法應該是快,但顯然這不是......
絕對是最完美的解決方案,謝謝@MaxU –
@Al_Iskander,歡迎您! :) – MaxU
沒錯,就是這樣,感謝@Seabass –