2016-06-11 58 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