我试图写一个熊猫数据帧(或可以使用numpy数组)到mysql数据库使用MysqlDB。MysqlDB似乎不理解'nan',我的数据库抛出一个错误,说nan不在字段列表中。我需要找到一种方法将“nan”转换为NoneType。
什么好主意吗?
我试图写一个熊猫数据帧(或可以使用numpy数组)到mysql数据库使用MysqlDB。MysqlDB似乎不理解'nan',我的数据库抛出一个错误,说nan不在字段列表中。我需要找到一种方法将“nan”转换为NoneType。
什么好主意吗?
当前回答
还有另一个选择,它确实对我有用:
df = df.astype(object).replace(np.nan, 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 = df.replace({np.nan: None})
注意:对于<1.4的pandas版本,这会将所有受影响列的dtype更改为object。 为了避免这种情况,请使用以下语法:
df = df.replace(np.nan, None)
这要归功于Github上的这个家伙和Killian Huyghe的评论。
还有另一个选择,它确实对我有用:
df = df.astype(object).replace(np.nan, None)
您是否有代码块需要检查?
使用.loc, pandas可以基于逻辑条件(过滤)访问记录并对它们执行操作(当使用=时)。将.loc掩码设置为某个值将会就地改变返回数组(所以这里要小心;我建议在使用代码块之前测试一个df副本)。
df.loc[df['SomeColumn'].isna(), 'SomeColumn'] = None
外层的函数是df。loc[row_label, column_label] =无。我们将使用.isna()方法为row_label使用布尔掩码,在SomeColumn列中查找“NoneType”值。
我们将使用.isna()方法返回列SomeColumn中的行/记录布尔数组,作为我们的row_label: df['SomeColumn'].isna()。它将分离SomeColumn中含有熊猫用.isna()方法检查的任何'NoneType'项的所有行。
我们将在屏蔽row_label的数据帧时使用column_label,并在标识我们想要用于.loc掩码的列时使用column_label。
最后,我们将.loc掩码设置为None,因此返回的行/记录将根据掩码索引更改为None。
下面是关于.loc和.isna()的pandas文档链接。
引用: https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.loc.html https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.isna.html
我相信最干净的方法是使用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)
]