【发布时间】:2020-06-05 03:45:58
【问题描述】:
我想 ffill 和 bfill 在 groupby 之后的特定列。
我的解决方案有效:
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 优化?
我在查看其他答案时运气不佳,例如 this 一个。
【问题讨论】:
-
“以这种格式”你真的是指组总是 4 行长,缺少第一个和最后一个元素,还是更能说明问题,即会有 一些 NaN 的条纹(任何长度),2 个非空值,然后是其他一些 NaN 的条纹?建议的解决方案仅适用于非常具体的第一种情况。
-
感谢您的提问;我的意思是这些组总是 4 行长,外面的两个值是 NaN,中间的两个值会被填充。
-
顺便说一句,您不需要那个 lambda,只需执行
df.groupby('A')['B'].ffill().bfill()。我怀疑它明显更快,只是更简单。 groupby 本身已经防止每个组中的第一个值被前一个组的最后一个值填充。 -
哦,天哪,我刚刚做了一些快速计时,将其扩展到大约 32,000 行。看起来
apply/lambda只是在谋杀这里的速度。仅仅像我之前的评论那样重写就会大大加快速度,下面的所有 3 个答案也是如此。 -
@JohnE 刚刚证实了你的发现,这太疯狂了!
标签: python pandas optimization