如何根据设置的条件在pandas数据帧中转发填充非空值

2024-04-26 02:33:19 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有以下数据帧:

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')

看起来像这样:

^{pr2}$

现在我想把给定列中最后一个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

但这似乎很尴尬,而且与熊猫的精神背道而驰(unpandonic?)。有什么更好的方法吗?在


Tags: columns数据代码dataframedffordateindex
2条回答

一种方法是用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

现在可以使用^{}将这些更改为2:

^{pr2}$

编辑:在这里使用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

这是一个非常通用的解决方案(例如,如果索引是非连续的,您将失败)。 第一部分,得到索引器是相当大的麻烦!在

In [64]: indexer = Series(df.index.get_indexer(df.diff().idxmin().values),index=df.columns)

In [65]: indexer
Out[65]: 
a    4
b    3
c    3
dtype: int64

我认为这是一种矢量化的方法,你所要做的就是根据上面的索引器构造正确的布尔矩阵,但是会让我的大脑受伤。在

^{pr2}$

相关问题 更多 >