Pandas dropna(subset)异常删除数据问题求助
排查步骤与解决方案
1. 核对列名的准确性
全量列DataFrame可能存在列名拼写/大小写不匹配的情况,比如实际列名为Serial_ID或number_id,而你指定的SERIAL_ID/NUMBER_ID并不存在于原数据中。这种情况下dropna会默认将所有行判定为符合删除条件(因为指定列不存在,等价于所有行的这些列都是NaN),导致误删有效数据。
排查代码:
# 验证目标列是否存在于原DataFrame print("SERIAL_ID" in df.columns) print("NUMBER_ID" in df.columns) # 输出所有列名逐一核对 print(df.columns.tolist())
2. 检查目标列的空值类型
全量列DataFrame中,SERIAL_ID或NUMBER_ID可能包含非标准空值(比如字符串'NaN'、'null'、空字符串''),这些值不会被pandas识别为真正的NaN。但在你提取3列副本时,可能因读取/复制操作的隐式转换,将这些值转为了标准NaN,导致两种场景下的空值判定逻辑不一致。
排查代码:
# 查看目标列的所有唯一值,确认是否存在非标准空值 print(df['SERIAL_ID'].unique()) print(df['NUMBER_ID'].unique()) # 统计非标准空值的数量 print(df[(df['SERIAL_ID'] == 'NaN') | (df['SERIAL_ID'] == '')].shape[0]) print(df[(df['NUMBER_ID'] == 'NaN') | (df['NUMBER_ID'] == '')].shape[0])
3. 排查索引异常问题
如果全量列DataFrame的索引存在重复、断裂或被篡改(比如之前的切片、合并操作导致索引混乱),可能干扰dropna的行匹配逻辑。而3列副本是重新生成的连续索引,规避了这个问题。
排查代码:
# 检查索引是否唯一、连续 print(df.index.is_unique) print(df.index.tolist())
4. 规避inplace=True的副作用
inplace=True会直接修改原DataFrame,若之前对原数据有未完成的链式操作、视图与副本混淆等情况,可能导致数据状态异常。建议先不使用inplace,生成新变量对比结果:
# 全量列数据清洗,不修改原数据 df_cleaned = df.dropna(subset=['SERIAL_ID', 'NUMBER_ID'], how='all') print(f"原数据行数:{df.shape[0]},清洗后行数:{df_cleaned.shape[0]}") # 3列副本清洗对比 df_3cols = df[['SERIAL_ID', 'NUMBER_ID', '任意其他列']] df_3cols_cleaned = df_3cols.dropna(subset=['SERIAL_ID', 'NUMBER_ID'], how='all') print(f"3列副本原行数:{df_3cols.shape[0]},清洗后行数:{df_3cols_cleaned.shape[0]}")
5. 检查pandas版本差异
不同版本的pandas对dropna的处理逻辑可能存在细微差异(比如对不存在的subset列的处理、空值判定规则)。可以先确认版本:
import pandas as pd print(pd.__version__)
若版本过低,尝试升级到最新稳定版后重新测试。
内容的提问来源于stack exchange,提问作者SbE
相关产品推荐
相关产品推荐

