繁体   English   中英

更快地向前填充和回填 groupby

[英]Faster way to forward-fill and back-fill a groupby

我想在ffill之后填充和bfill特定的列。

我的解决方案有效:

import numpy as np
import pandas as pd

df = pd.DataFrame({
    "A": [1, 1, 1, 1, 2, 2, 2, 2],
    "B": [np.nan, 'f1', 'b1', np.nan, np.nan, 'f2', 'b2', np.nan]
})
df['B'] = df.groupby('A')['B'].apply(lambda _: _.ffill().bfill())

所以这:

    A   B
0   1   NaN
1   1   f1
2   1   b1
3   1   NaN
4   2   NaN
5   2   f2
6   2   b2
7   2   NaN

变成这样:

    A   B
0   1   f1
1   1   f1
2   1   b1
3   1   b1
4   2   f2
5   2   f2
6   2   b2
7   2   b2

请注意,我要填充和 bfill 的序列将始终采用这种格式( Nan, x, y, Nan

虽然这可行,但在大型数据帧上速度非常慢。

我正在寻找一些优化以使其更快(理想情况下不使用 Dask 或多处理),也许我可以进行 Numpy 优化?

我没有很多运气看其他答案,比如这个

如果你想要速度,避免 groupby 并使用 numpy 而不是 pandas 是很好的规则。 这通常是不可能的,但在这里你有非常规则的数据的特殊情况,你所需要的只是[start:end:stride]形式的下标三元组:

df.iloc[0::4,1] = df.iloc[1::4,1].values
df.iloc[3::4,1] = df.iloc[2::4,1].values

说明:大多数人都知道您可以使用[start:stop]形式的下标,但您也可以添加一个可选的stride参数。 所以第一行说用元素 1,5,9,... 替换元素 0,4,8,... “值”是删除 pandas 索引所必需的,这实际上是有害的。

仅仅通过避免 groupby,这应该会更快一些。 For a little more speed, you could output column B to numpy, do work in numpy (basically the same code), and then reimport to pandas:

arr = df.B.values
arr[0::4] = arr[1::4]  
arr[3::4] = arr[2::4]
df.B = arr

如果您想留在 pandas 中,您可以做的另一件事是取消堆叠,复制整个列,然后重新堆叠。 无论如何,这基本上就是上面的代码正在做的事情。 老实说,对于这样一个矩形问题,任何数组样式的方法都会相当快。

如果您的数据确实具有连续组的良好结构,那么您可以通过使用ffillbfill中的limit参数来避免groupby ,例如:

print (df['B'].ffill(limit=1).bfill(limit=1))
0    f1
1    f1
2    b1
3    b1
4    f2
5    f2
6    b2
7    b2
Name: B, dtype: object

如果你的格式是前缀为(Nan, x, y, Nan) ,什么时候可以做

df.B=df.groupby([df.A,df.index//2]).B.transform('first')
Out[169]: 
    B
0  f1
1  f1
2  b1
3  b1
4  f2
5  f2
6  b2
7  b2

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM