如何在DataFrame的rowid列将NaN替换为None且避免SettingWithCopyWarning
问题:DataFrame中rowid列NaN替换为None的解决方法
原始DataFrame结构:
x u i rowid 0 1.0 1.0 5.0 1.0 1 2.0 2.0 4.0 2.0 2 3.0 3.0 3.0 3.0 3 4.0 4.0 2.0 NaN 4 5.0 5.0 1.0 5.0 5 6.0 4.0 0.0 6.0 6 7.0 3.0 1.0 7.0 7 8.0 2.0 2.0 NaN 8 9.0 1.0 3.0 9.0 9 10.0 0.0 4.0 10.0 10 11.0 1.0 5.0 11.0 11 12.0 2.0 3.0 12.0 12 13.0 3.0 2.0 NaN 13 14.0 4.0 1.0 14.0 14 15.0 5.0 0.0 15.0 16 17.0 3.0 2.0 17.0
遇到的问题
- 使用
data_frame = data_frame.where(pandas.notnull(data_frame), None)时触发SettingWithCopyWarning警告:
/usr/lib/python3.8/site-packages/pandas/core/indexing.py:1843: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
- 尝试
data_frame.loc[numpy.isnan(data_frame[ROW_ID]), ROW_ID] = None无效,但将None替换为-1时可以成功替换NaN。
原因分析
- pandas的数值型列(如float类型的rowid)无法直接存储None,None会被自动转换为NaN;而-1是数值类型,能和列类型匹配,因此替换成功。
SettingWithCopyWarning是因为当前操作的DataFrame可能是另一个DataFrame的切片副本,而非原始对象。
解决方案
方案1:转换列类型后替换
先将rowid列转为object类型(支持混合存储数值和None),再替换NaN:
import pandas as pd import numpy as np # 转换列类型为object data_frame['rowid'] = data_frame['rowid'].astype(object) # 定位NaN并替换为None data_frame.loc[pd.isna(data_frame['rowid']), 'rowid'] = None
方案2:创建副本避免警告
如果当前DataFrame是切片副本,先显式创建副本再操作:
# 创建DataFrame副本 data_frame = data_frame.copy() # 转换类型并替换 data_frame['rowid'] = data_frame['rowid'].astype(object) data_frame.loc[pd.isna(data_frame['rowid']), 'rowid'] = None
方案3:使用replace方法简化操作
data_frame['rowid'] = data_frame['rowid'].astype(object).replace(np.nan, None)
内容的提问来源于stack exchange,提问作者bux
相关产品推荐
相关产品推荐

