pandas写入数据库时出错:nan can't be used with mysql
pandas
写入数据库时出错的解决方法
在使用pandas
将一段数据写入数据库时,由于数据中存在NaN
值,导致写入数据库出错。
这时候需要将NaN
值替换成None
才能写入数据库,否则会出现以下错误:
nan can't be used with mysql
为了把NaN
值替换成None
,在不同的pandas
版本下做法是不同的。
pandas
2.0以前的版本
pandas
2.0以前的版本可以直接使用where()
函数,例如:
>>> import pandas as pd
>>> import numpy as np
>>> pd.__version__
'1.1.5'
>>> df = pd.DataFrame({'a':[1,2,3,4,5], 'b':[1,2,3,4,5]})
>>> df['a'].iloc[1] = np.nan
a b
0 1.0 1
1 NaN 2
2 3.0 3
3 4.0 4
4 5.0 5
>>> df.where(pd.notna(df), None)
a b
0 1 1
1 None 2
2 3 3
3 4 4
4 5 5
pandas
2.0以上版本
但上面的做法在2.0以上版本的pandas
不起作用,因为pandas
不会主动改变一列的数据类型,如果原来的列数据类型一致,其中仅含有NaN
值,这时照前面的做法,DataFrame
是不会改变的:
>>> import pandas as pd
>>> import numpy as np
>>> pd.__version__
'2.0.3'
>>> df = pd.DataFrame({'a':[1,2,3,4,5], 'b':[1,2,3,4,5]})
>>> df['a'].iloc[1] = np.nan
>>> df
a b
0 1.0 1
1 NaN 2
2 3.0 3
3 4.0 4
4 5.0 5
>>> df.where(pd.notna(df), None)
a b
0 1.0 1
1 NaN 2
2 3.0 3
3 4.0 4
4 5.0 5
此时应该多一步操作,就可以得到想要的结果了:
>> df.replace(np.nan, None)
a b
0 1.0 1
1 None 2
2 3.0 3
3 4.0 4
4 5.0 5
但是如果A列本身数据类型就不一致,那么可以直接用where()
替换:
>>> df = pd.DataFrame({'a':[1,2,3,4,5], 'b':[1,2,3,4,5]})
>>> df['a'].iloc[1] = 'None'
>>> df
a b
0 1 1
1 None 2
2 3 3
3 4 4
4 5 5
>>> df.where(pd.notna(df), None)
a b
0 1 1
1 None 2
2 3 3
3 4 4
4 5 5
2.0以前版本的pandas
是否能采用2.0以上版本的方法替换成None
?
值得说一句,在2.0以下版本的pandas
中是不能直接使用replace()
的,请看:
>>> pd.__version__
'1.1.5'
>>> df = pd.DataFrame({'a':[1,2,3,4,5], 'b':[1,2,3,4,5]})
>>> df['a'].iloc[1] = np.nan
>>> df
a b
0 1.0 1
1 NaN 2
2 3.0 3
3 4.0 4
4 5.0 5
>>> df.replace(np.nan, None)
a b
0 1.0 1
1 1.0 2 # 注意看这里,替换成None不成功
2 3.0 3
3 4.0 4
4 5.0 5
因此,如果您的代码中需要兼顾2.0以上和2.0以前的pandas
,只能做版本判断并分别处理了。