如何处理Pandas fillna中的“None”值

53
我有以下字典: fillna(value = {'first_name':'Andrii','last_name':'Furmanets','created_at':None}) 当我将该字典传递给fillna时,我看到:

raise ValueError('must specify a fill method or value')\nValueError: must specify a fill method or value\n"

对我来说,它似乎失败了,因为它遇到了None值。
我使用的是 pandas 版本0.20.3。

2
在浮点列中,None 实际上是由 np.nan(以及大多数类型)表示的。因此这没有任何意义。请参阅此处的文档:https://github.com/pandas-dev/pandas/issues/10871 - BENY
d= {'first_name': 'Andrii', 'last_name':'Furmanets'} - BENY
字典来自外部并必须通过pandas进行处理,其中有一个created_at字段,我认为它可以与pandas 0.18.0一起使用。 - Andrii Furmanets
试图用 None 来填充日期时间是一个糟糕的想法,这就是 pandas NaT(NotATime)的作用:用于丢失的日期时间。 - smci
5个回答

91

假如您想要使用Python的None来规范化所有的空值。

df.fillna(np.nan).replace([np.nan], [None])

第一个fillna将会用Numpy的NaN替换所有的(None, NAT, np.nan等),然后再用Python的None替换Numpy的NaN。


5
对我来说,这是将None应用于整个数据框的最简单方法。 - su79eu7k
6
df.replace([np.nan], [None]) 这就足够了。 - mangusta
1
@mangusta 对于大多数情况,你是正确的,但如果你有其他类型的 null(例如 pd.NaT),在 replace 之后你不一定会得到 Python 的 None。从 fillna 开始更加一致。 - AsaridBeck91
1
有人能解释一下为什么这个方法有效吗?在我的情况中,我只使用了.replace({np.nan: None})而没有使用.fillna()。我想把所有的nan值转换成None,但有时候我有一个完美的DF,其中没有nan,只有一些None值,但是.replace()却把所有的None都转换成了nan,这不是它应该做的相反操作吗? - rain01
2
为什么列表括号是必需的? - michen00
显示剩余4条评论

23

设置
考虑示例数据框 df

df = pd.DataFrame(dict(A=[1, None], B=[None, 2], C=[None, 'D']))

df

     A    B     C
0  1.0  NaN  None
1  NaN  2.0     D

我可以确认这个错误

df.fillna(dict(A=1, B=None, C=4))
ValueError: must specify a fill method or value
这是因为 pandas 正在循环遍历字典中的键,并针对每个相关列执行 fillna。如果查看 pd.Series.fillna 方法的签名,您会发现这一点。
Series.fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None, **kwargs)

您会看到默认值为None。因此,我们可以使用以下方法复制此错误:

df.A.fillna(None)

或者等价地

df.A.fillna()

我想补充一点,考虑到您试图使用空值填充空值,我并不感到意外。


你需要的是一个解决方法

解决方案
对于想要填充非空值的列,请使用 pd.DataFrame.fillna。然后,在您想要用另一个空值替换的特定列上进行 pd.DataFrame.replace

df.fillna(dict(A=1, C=2)).replace(dict(B={np.nan: None}))

     A     B  C
0  1.0  None  2
1  1.0     2  D

我在 fillna 中将 value 作为参数,像这样:df.fillna(value=dict(A=1, B=None, C=4)) - Andrii Furmanets
这是一样的吗? - Andrii Furmanets
是的,它是一样的。 - piRSquared
对我来说('1.0.3'),df.fillna(value=dict(A=1, B=None, C=4)) 会出现相同的 ValueError。 - Mr_and_Mrs_D
你正在尝试使用空值填充空值,这是非常错误的结论。None与Not A Number不同。None或''返回'',但是np.nan或''返回np.nan。现在尝试对其执行一些字符串操作。 - anishtain4

3
你使用了什么类型的数据结构?这适用于pandas Series:

你使用了什么类型的数据结构?这适用于pandas系列:

import pandas as pd

d = pd.Series({'first_name': 'Andrii', 'last_name':'Furmanets', 'created_at':None})
d = d.fillna('DATE')

我使用字典而不是字符串。 - Andrii Furmanets
你试图用什么来替换 None - atwalsh
1
它甚至可以是“None”。 - Andrii Furmanets
在将字典放入 fillna 之前,我会对其进行规范化处理,正如您所提到的。谢谢。 - Andrii Furmanets

2

使用替代方法以 None 来填充空值。我使用的是 pandas 0.24.0 版本,并且这样做是为了将 NULL 值插入到 POSTGRES 数据库中。

最初的回答:

# Stealing @pIRSquared dataframe
df = pd.DataFrame(dict(A=[1, None], B=[None, 2], C=[None, 'D']))

df

     A    B     C
0  1.0  NaN  None
1  NaN  2.0     D

# fill NaN with None. Basically it says, fill with None whenever you see NULL value.
df['A'] = np.where(df['A'].isnull(), None, df['A'])
df['B'] = np.where(df['B'].isnull(), None, df['B'])

# Result
df

     A    B     C
0  1.0  None  None
1  None  2.0     D


IndexError: 只有整数、切片(:)、省略号(...)、numpy.newaxis(None)和整数或布尔数组是有效的索引。很遗憾,我无法提供示例,因为它们是具有敏感数据的大型数据帧。你有什么想法可能出了什么问题? - user1717828

-1
解决方案:使用pandas的pd.NA而不是基本的Python的None。
df = pd.DataFrame({'first_name':pd.NA, 'last_name':pd.NA, 'created_at':pd.NA})

df.fillna(value={'first_name':'Andrii', 'last_name':'Furmanets', 'created_at':pd.NA})

通常最好将pandas的NA保持不变。不要试图改变它。NA的存在是一种特性,而不是问题。在其他pandas函数中(但不包括numpy),NA会被正确处理。
如果你坚持认为Python的None应该替换pandas的NA,因为某些下游原因,那么请向我们展示在NA引起问题的地方后面缺失的代码;这通常是一个XY问题。

1
这不是一个答案? - Henry Henrinson
@HenryHenrinson:这绝对是一个答案(保留NaT不变,不替换它),并且在大多数情况下避免了后续问题,这也是由pandas文档推荐的,并且pandas函数能够处理NaT。OP没有展示出任何NaT实际上引起问题的下游代码。我编辑了答案以添加这个解释。 - smci
@HenryHenrinson:那就是 NA,不是 NaT。这仍然是正确的答案:NaN 通常在 pandas 中非常有用,在聚合、连接等操作中都可以工作。原问题提出者还没有展示出 NA 实际上引起了问题的任何后续代码,因此这是一个 XY 问题:仅仅因为他们坚持需要填充 NA,并不意味着他们一定需要这样做。 - smci
@HenryHenrinson:NA、NaN(以及NaT)是完全兼容pandas的值;而基本的Python None则不是。这就是底线,也是我过去四年一直在坚持的观点。看看pandas文档,他们并不推荐将None作为惯用的pandas写法。 - smci
1
@mike01010 .to_csv() 将其写成 NaN 或 None;这取决于设置 na_rep,默认为空字符串 ('')。 - undefined
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接