为何DataFrame单行链式调用中fillna()不生效?如何实现单行写法?
问题原因与解决方案
为什么单行写法的fillna不生效?
核心差异在于**fillna(0)的作用对象完全不同**:
- 拆分两步执行时:
第一步把筛选后(仅Event='A'且Direction='UP')的分组累计计数结果赋值给df['prev'],此时原DataFrame中不满足筛选条件的行,因为索引不匹配,prev列会被填充为NaN;
第二步的fillna(0)是对整个df['prev']列操作,把所有NaN替换成0,所以结果正确。 - 合并单行执行时:
fillna(0)是在筛选后的短Series上调用的——这个短Series里只有符合条件的行,cumcount()生成的是连续整数,本身没有NaN,所以fillna(0)等于没起作用。之后把这个短Series赋值给df['prev'],那些不匹配索引的行还是会变成NaN,看起来就像fillna失效了。
可行的单行写法
可以用transform方法在原DataFrame的分组内完成计算,直接生成和原df长度一致的结果,再填充0:
df['prev'] = df.groupby('group').transform(lambda x: x[(x.Event == 'A') & (x.Direction == 'UP')].cumcount().add(1)).fillna(0)
或者更高效的方式,先标记符合条件的行,再分组累计计数(避免重复筛选):
df['prev'] = (df .assign(flag=(df.Event == 'A') & (df.Direction == 'UP')) .groupby('group')['flag'] .transform(lambda g: g.cumsum() * g) .fillna(0) )
内容的提问来源于stack exchange,提问作者Alex DiS
相关产品推荐
相关产品推荐

