使用None替换Pandas或Numpy Nan以与MysqlDB一起使用

Ris*_*shi 99 python numpy mysql-python pandas

我正在尝试使用MysqlDB将一个Pandas数据帧(或者可以使用numpy数组)写入mysql数据库.MysqlDB似乎不理解'nan',我的数据库抛出一个错误,说nan不在字段列表中.我需要找到一种方法将'nan'转换为NoneType.

有任何想法吗?

And*_*den 155

@bogatron说得对,你可以使用where,值得注意的是你可以在熊猫中本地做到这一点:

df1 = df.where((pd.notnull(df)), None)
Run Code Online (Sandbox Code Playgroud)

注意:这会将所有列的dtype更改为object.

例:

In [1]: df = pd.DataFrame([1, np.nan])

In [2]: df
Out[2]: 
    0
0   1
1 NaN

In [3]: df1 = df.where((pd.notnull(df)), None)

In [4]: df1
Out[4]: 
      0
0     1
1  None
Run Code Online (Sandbox Code Playgroud)

注意:您不能重做DataFrames dtype以允许所有数据类型类型,使用astype,然后使用DataFrame fillna方法:

df1 = df.astype(object).replace(np.nan, 'None')
Run Code Online (Sandbox Code Playgroud)

不幸的是,无论是这个还是使用replace,都None看不到这个(封闭的)问题.


顺便说一句,值得注意的是,对于大多数用例,您不需要将NaN替换为None,请参阅关于pandas中NaN和None之间差异的问题.

但是,在这个特定的情况下,你似乎(至少在这个答案的时候).

  • 使用 `df.where(pd.notnull(df), None)` 不再适用于 1.3.0 - 相反,我从 @EliadL 找到了下一个答案仍然可以正常工作:/sf/answers/3808259381/ 2407819 (3认同)
  • 一个重要的用例是转换为 JSON。并非所有语言都支持 JSON 中的 NaN(例如 PHP),因此需要将它们转换为 None。作为一名数据科学家,这是我经常遇到的事情。 (2认同)

Eli*_*adL 47

df = df.replace({pd.np.nan: None})
Run Code Online (Sandbox Code Playgroud)

Github问题上,这个家伙可以归功于这个人.

  • 这是最好的答案,因为您可以使用“df.replace({np.nan: None})”作为临时对象 (8认同)
  • **对于 pandas 版本 <1.3.0** 如果“df”中的值已经是“None”,此答案会将它们切换回“np.nan” (6认同)
  • 对于 pandas 版本<1.4,在替换中使用字典时存在错误,并且您的列数据类型可能会意外更改,您应该更喜欢这种语法:`df = df.replace(np.nan, None)`。请参阅https://github.com/pandas-dev/pandas/issues/35268 (4认同)
  • 如果“df”中的值已经是“None”,这个答案会将它们切换回“np.nan” (3认同)
  • 我不知道您可以像这样进入numpy名称空间。整齐。如果已经导入,则df = df.replace({np.nan:None})也可以 (2认同)

bog*_*ron 15

您可以替换nanNone您numpy的数组中:

>>> x = np.array([1, np.nan, 3])
>>> y = np.where(np.isnan(x), None, x)
>>> print y
[1.0 None 3.0]
>>> print type(y[1])
<type 'NoneType'>
Run Code Online (Sandbox Code Playgroud)

  • 唯一潜在的问题是dtype的更改,x.dtype是dtype('float64'),而y.dtype是dtype('object')。 (2认同)

Max*_*gal 12

在不同版本的 pandas 中,替换np.nan为的实现None方式有所不同:

if version.parse(pd.__version__) >= version.parse('1.3.0'):
    df = df.replace({np.nan: None})
else:
    df = df.where(pd.notnull(df), None)
Run Code Online (Sandbox Code Playgroud)

这解决了以下问题:对于 pandas 版本 <1.3.0,如果 中的值df已经存在Nonedf.replace({np.nan: None})则将它们切换回np.nan ,反之亦然


小智 9

磕磕绊绊后,这对我有用:

df = df.astype(object).where(pd.notnull(df),None)
Run Code Online (Sandbox Code Playgroud)


gaa*_*aan 7

另外除了:更换倍数和转换从柱背面的类型时要小心对象浮动。如果您想确定您的None's 不会翻转回np.NaN's 应用@andy-hayden 的建议使用pd.where. 替换如何仍然“出错”的说明:

In [1]: import pandas as pd

In [2]: import numpy as np

In [3]: df = pd.DataFrame({"a": [1, np.NAN, np.inf]})

In [4]: df
Out[4]:
     a
0  1.0
1  NaN
2  inf

In [5]: df.replace({np.NAN: None})
Out[5]:
      a
0     1
1  None
2   inf

In [6]: df.replace({np.NAN: None, np.inf: None})
Out[6]:
     a
0  1.0
1  NaN
2  NaN

In [7]: df.where((pd.notnull(df)), None).replace({np.inf: None})
Out[7]:
     a
0  1.0
1  NaN
2  NaN
Run Code Online (Sandbox Code Playgroud)


YaO*_*OzI 6

只是对@Andy Hayden 的回答的补充:

由于DataFrame.mask是 的对立孪生DataFrame.where,因此它们具有完全相同的签名但具有相反的含义:

  • DataFrame.where对于替换条件为False 的很有用
  • DataFrame.mask用于替换条件为True 的值。

所以在这个问题中,使用df.mask(df.isna(), other=None, inplace=True)可能更直观。