假设我有以下数据框:
df = pd.DataFrame({'a':[0,0,0,1,0,0], 'b':[0,0,1,0,0,0], 'c':[0,1,1,0,0,0]})
df.index = pd.date_range('2000-03-02', periods=6, freq='D')
看起来像这样:
a b c
2000-03-02 0 0 0
2000-03-03 0 0 1
2000-03-04 0 1 1
2000-03-05 1 0 0
2000-03-06 0 0 0
2000-03-07 0 0 0
现在我想将给定列中最后一个 1 之后出现的每个值设置为 2。所需的结果如下所示:
a b c
2000-03-02 0 0 0
2000-03-03 0 0 1
2000-03-04 0 1 1
2000-03-05 2 2 2
2000-03-06 2 2 2
2000-03-07 2 2 2
我有这段代码,它可以工作:
cols = df.columns
for col in cols:
s = df[col]
x = s[s==1].index[-1]
df[col][(x + 1):] = 2
但这看起来相当尴尬,并且违背了 pandas 的精神(非 Pandonic?)。有更好的方法建议吗?
最佳答案
一种方法是replace
带有 NaN 的较低零:
In [11]: df.replace(0, np.nan).bfill() # maybe neater way to do this?
Out[11]:
a b c
2000-03-02 1 1 1
2000-03-03 1 1 1
2000-03-04 1 1 1
2000-03-05 1 NaN NaN
2000-03-06 NaN NaN NaN
2000-03-07 NaN NaN NaN
现在您可以使用where
将它们更改为 2:
In [12]: df.where(df.replace(0, np.nan).bfill(), 2)
Out[12]:
a b c
2000-03-02 0 0 0
2000-03-03 0 0 1
2000-03-04 0 1 1
2000-03-05 1 2 2
2000-03-06 2 2 2
2000-03-07 2 2 2
编辑:在这里使用 cumsum 的技巧可能会更快:
In [21]: %timeit df.where(df.replace(0, np.nan).bfill(), 2)
100 loops, best of 3: 2.34 ms per loop
In [22]: %timeit df.where(df[::-1].cumsum()[::-1], 2)
1000 loops, best of 3: 1.7 ms per loop
In [23]: %timeit pd.DataFrame(np.where(np.cumsum(df.values[::-1], 0)[::-1], df.values, 2), df.index)
10000 loops, best of 3: 186 µs per loop
关于python - 如何根据设定的条件转发pandas数据框中的填充非空值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22083378/