You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas链式调用drop_duplicates().fillna(0)无法填充NaN为0的问题

嘿,这个问题我在旧版Pandas里也踩过坑!咱们先搞清楚为什么链式调用会失效,再给你几个优雅的解决办法~

问题根源:索引对齐与旧版方法特性

你遇到的核心问题在于Pandas的索引对齐机制,以及0.20.3版本中drop_duplicates()的返回逻辑:

  • 当你执行df['a'].drop_duplicates()时,它返回的是仅保留唯一值(第一个出现的)的Series,但这个Series只包含有值的索引(比如你的例子里是0、2、3、5),索引1和4的条目直接被移除了,而非设为NaN。
  • 链式调用fillna(0)时,这个方法只会对Series中已存在索引但值为NaN的位置填充0,但此时临时Series里根本没有索引1和4,所以填充操作对这两个位置完全无效。
  • 当你把结果赋值回df['a']时,Pandas会按索引对齐,找不到对应索引的值就自动设为NaN,这就是为什么结果里仍有NaN。

而分开执行时,第一步赋值会把原DataFrame中缺失的索引位置(1、4)自动补为NaN,第二步fillna(0)是对整个df['a'](包含所有索引且存在NaN)进行填充,所以能生效。

解决办法

办法1:补全索引后链式填充(贴近你的原有思路)

用reindex先恢复原DataFrame的所有索引,让缺失位置变成NaN,再执行填充,完美适配链式调用:

df = pd.DataFrame({'a':[1,1,2,3,3,4], 'b':[10,20,30,40,50,60]})
df['a'] = df['a'].drop_duplicates().reindex(df.index).fillna(0)

执行后结果符合预期:

a   b
0  1  10
1  0  20
2  2  30
3  3  40
4  0  50
5  4  60

办法2:直接标记重复值替换(更高效)

不需要先删再填充,直接用duplicated()标记重复项(保留第一个),然后把这些位置设为0,一步到位:

df.loc[df['a'].duplicated(keep='first'), 'a'] = 0

这个方法无需生成临时Series,直接在原DataFrame上修改,效率更高。

办法3:链式风格的替换写法

如果你偏好链式调用的简洁性,也可以用replace结合duplicated实现:

df['a'] = df['a'].replace(df['a'][df['a'].duplicated()], 0)

内容的提问来源于stack exchange,提问作者elPastor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:43:27