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

我想在 groupbyffill之后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

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


虽然这有效,但它在大型数据帧上非常慢。


我正在寻找一些优化来加快速度(理想情况下不求助于使用 Dask 或多处理),也许我可以进行 Numpy 优化?


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


翻翻过去那场雪
浏览 105回答 3
3回答

慕慕森

如果你想要速度,避免使用 groupby 并使用 numpy 而不是 pandas 是可以遵循的好规则。这通常是不可能的,但在这里你有非常规则的数据的特殊情况,你所需要的只是形式的下标三元组[start:end:stride]:df.iloc[0::4,1] = df.iloc[1::4,1].valuesdf.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.valuesarr[0::4] = arr[1::4]  arr[3::4] = arr[2::4]df.B = arr如果您想留在 pandas 中,您可以做的另一件事是取消堆叠,复制整个列,然后重新堆叠。无论如何,这基本上就是上面的代码所做的。老实说,对于这种矩形类型的问题,任何数组样式的方法都会相当快。

qq_笑_17

如果您的数据确实具有连续组的良好结构,那么您可以groupby通过使用limit参数 inffill和bfilllike 来避免:print (df['B'].ffill(limit=1).bfill(limit=1))0    f11    f12    b13    b14    f25    f26    b27    b2Name: B, dtype: object

一只斗牛犬

如果你的格式是前缀 as (Nan, x, y, Nan),什么时候可以做df.B=df.groupby([df.A,df.index//2]).B.transform('first')Out[169]:     B0  f11  f12  b13  b14  f25  f26  b27  b2
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python