为了账号安全,请及时绑定邮箱和手机立即绑定

向前填充和回填 groupby 的更快方法

向前填充和回填 groupby 的更快方法

翻翻过去那场雪 2022-12-27 15:23:04
我想在 groupbyffill之后bfill的特定列。我的解决方案有效:import numpy as npimport pandas as pddf = 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   B0   1   NaN1   1   f12   1   b13   1   NaN4   2   NaN5   2   f26   2   b27   2   NaN变成这样:    A   B0   1   f11   1   f12   1   b13   1   b14   2   f25   2   f26   2   b27   2   b2请注意,我要 ffill 和 bfill 的序列将始终采用这种格式 ( Nan, x, y, Nan)虽然这有效,但它在大型数据帧上非常慢。我正在寻找一些优化来加快速度(理想情况下不求助于使用 Dask 或多处理),也许我可以进行 Numpy 优化?我没有太多运气看其他答案,比如这个。
查看完整描述

3 回答

?
慕慕森

TA贡献1856条经验 获得超17个赞

如果你想要速度,避免使用 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

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


通过避免 groupby,这应该会更快一些。为了提高速度,您可以将 B 列输出到 numpy,在 numpy 中工作(基本上是相同的代码),然后重新导入到 pandas:


arr = df.B.values

arr[0::4] = arr[1::4]  

arr[3::4] = arr[2::4]

df.B = arr

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


查看完整回答
反对 回复 2022-12-27
?
qq_笑_17

TA贡献1818条经验 获得超7个赞

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


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


查看完整回答
反对 回复 2022-12-27
?
一只斗牛犬

TA贡献1784条经验 获得超2个赞

如果你的格式是前缀 as (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


查看完整回答
反对 回复 2022-12-27
  • 3 回答
  • 0 关注
  • 100 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信