【问题标题】:pandas replace NaN to None exhibits counterintuitive behaviourpandas 将 NaN 替换为 None 表现出违反直觉的行为
【发布时间】:2019-05-29 23:53:27
【问题描述】:

给定一个系列

s = pd.Series([1.1, 1.2, np.nan])
s
0    1.1
1    1.2
2    NaN
dtype: float64

如果需要将 NaN 转换为 None(例如,使用镶木地板),那么我想要

0     1.1
1     1.2
2    None
dtype: object

我认为Series.replace 是这样做的明显方式,但这是函数返回的内容:

s.replace(np.nan, None)

0    1.1
1    1.2
2    1.2
dtype: float64

NaN 被向前填充,而不是被替换。通过docs,我看到如果第二个参数是None,那么第一个参数应该是一个字典。基于此,我希望replace 能够按预期替换,或者抛出异常。

我相信这里的解决方法是

pd.Series([x if pd.notna(x) else None for x in s], dtype=object) 
0     1.1
1     1.2
2    None
dtype: object

这很好。但我想了解为什么会发生这种行为,无论是记录在案,还是只是一个错误,我必须清理我的 git 配置文件并在问题跟踪器上记录一个......有什么想法吗?

【问题讨论】:

  • s.where(s.notnull(),None) 我猜是另一个更干净的解决方法
  • 对我来说这看起来像一个错误,我希望它会抛出异常或什么都不做,前向填充不正确,我会将其作为问题提交:github.com/pandas-dev/pandas/issues
  • @coldspeed 是的,现在我明白了,它不一样了。现在最糟糕的部分是我正在经历一些我自己的实现,只是为了检查一个错误是否因此而蔓延。感谢您的提问! s.replace(np.nan, None) 在向前填充时实际上是违反直觉的
  • 这工作 s.replace({np.nan:None}) 但我希望不那么冗长的方法表现相同
  • 这是 Nicki 的workaround。如果您收到对此的权威回复,我们可能会将其作为重复项关闭。

标签: python pandas replace


【解决方案1】:

此行为在method 参数的文档中:

method : {‘pad’, ‘ffill’, ‘bfill’, None}

The method to use when for replacement, when to_replace is a scalar, list or tuple and value is None.

所以在你的例子中to_replace 是一个标量valueNone。方法默认为pad,来自fillna的文档:

pad / ffill: propagate last valid observation forward to next valid

【讨论】:

  • 这仍然不能解释为什么 NaN 是向前填充的?
  • 嗯,这表明s.replace(np.nan, None, method=None) 可以工作,但它没有,而且很糟糕
  • @coldspeed 默认方法是pad
  • 对我来说这是出乎意料的,这是一个特殊的边缘情况,这不是我所期望的,因为如果没有匹配说s.replace('foo',None),那么它将返回原始系列不变
  • @ayhan 啊好的,对我来说这很奇怪,它可能不会被更改,因为它已记录但对我来说出乎意料,我不希望这种行为发生,通常没有任何事情发生或完全匹配的值被替换,因此我不会使用replaceffillbfill
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-06
  • 2017-06-21
  • 2018-03-26
  • 2018-01-07
  • 2018-05-19
  • 2020-12-15
相关资源
最近更新 更多