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

什么好主意吗?


当前回答

我相信最干净的方法是使用pandas. datafframe .to_numpy()方法中的na_value参数(docs):

na_value:任意,可选 用于缺失值的值。默认值取决于dtype和DataFrame列的dtypes。 1.1.0新版功能。

例如,你可以使用None替换NaN的字典

columns = df.columns.tolist()
dicts_with_nan_replaced = [
    dict(zip(columns, x))
    for x in df.to_numpy(na_value=None)
]

其他回答

你可以在numpy数组中用None替换nan:

>>> 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'>

我相信最干净的方法是使用pandas. datafframe .to_numpy()方法中的na_value参数(docs):

na_value:任意,可选 用于缺失值的值。默认值取决于dtype和DataFrame列的dtypes。 1.1.0新版功能。

例如,你可以使用None替换NaN的字典

columns = df.columns.tolist()
dicts_with_nan_replaced = [
    dict(zip(columns, x))
    for x in df.to_numpy(na_value=None)
]

@bogatron是对的,你可以用where,值得注意的是,你可以在熊猫的原生环境中这样做:

df1 = df.where(pd.notnull(df), None)

注意:这将所有列的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

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

df1 = df.astype(object).replace(np.nan, 'None')

不幸的是,这和使用replace都不能与None一起工作,看到这个(关闭)问题。


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

然而,在这个特定的情况下,你似乎是这样的(至少在回答这个问题的时候)。

很老了,但我偶然发现了同样的问题。 试着这样做:

df['col_replaced'] = df['col_with_npnans'].apply(lambda x: None if np.isnan(x) else x)

现在对我来说,徒手做是唯一可行的方法。

@rodney cox的回答几乎在所有情况下都对我有效。

下面的代码将所有列设置为对象数据类型,然后将任何空值替换为None。将列数据类型设置为object非常重要,因为这样可以防止pandas进一步更改类型。

for col in df.columns:
    df[col] = df[col].astype(object)
    df.loc[df[col].isnull(), col] = None

警告:此解决方案效率不高,因为它处理的列可能没有np。nan值。