Jupyter循环填充DataFrame空值后仍存在空值的问题排查
问题原因分析与解决方案
我之前也碰到过Jupyter Notebook里Pandas操作的类似坑,来帮你拆解下这个问题:
核心原因:Jupyter中Pandas的视图与副本差异
在Jupyter环境里,当你用for col in df:遍历列名,直接对df[col]执行fillna操作时,有时候df[col]返回的是原DataFrame的副本而非视图。这就导致你在循环里修改的只是临时副本,原DataFrame根本没被改动——循环内打印的df[col].isnull().sum()显示0,是因为你刚修改了当前遍历到的副本对象,但原DataFrame的LotFrontage列其实完全没更新。
为什么PyCharm里运行正常?因为PyCharm的执行环境中,df[col]更大概率返回的是原数据的视图,修改操作会直接同步到原DataFrame上。这本质是Pandas的SettingWithCopyWarning背后的机制:当链式索引或某些列访问方式返回副本时,修改操作不会作用到原数据。
可靠的解决方法
这里有几种能避开视图/副本坑的写法:
方法1:用df.loc明确操作原DataFrame
通过loc定位列,确保修改的是原数据而非副本:
for col in df.columns: # 获取列的众数 mode_val = df[col].value_counts().index[0] # 用loc明确修改原DataFrame的列 df.loc[:, col] = df[col].fillna(mode_val) print(df[col].isnull().sum()) print(df.isnull().sum())
方法2:用apply批量处理(更简洁的向量化写法)
Pandas更推荐向量化操作,避免循环带来的隐患,试试apply:
df = df.apply(lambda col: col.fillna(col.value_counts().index[0])) print(df.isnull().sum())
方法3:开启警告提示提前排查
在Jupyter里运行代码前,开启Pandas的链式赋值警告,能快速定位副本修改问题:
import pandas as pd pd.set_option('mode.chained_assignment', 'warn')
如果运行时弹出SettingWithCopyWarning,就说明你正在修改副本,需要调整代码写法。
内容的提问来源于stack exchange,提问作者CezarySzulc
相关产品推荐
相关产品推荐

