遍历Pandas Series后值丢失问题排查与解决求助
Pandas遍历Series值丢失问题分析与解决
问题重现
遍历X_train列之前执行以下代码:
print('SaleCondition', X_train['SaleCondition'].values.tolist())
输出正常的非空值列表:
SaleCondition ['Partial', 'Normal', ...]
但在遍历列的循环中,当i='SaleCondition'时执行相同打印语句,输出为空列表:
for i in X_train.columns: if i == 'SaleCondition': print('SaleCondition', X_train['SaleCondition'].values.tolist()) # 此处输出为空 X_train[i] = X_train[i].astype(str) X_train = pd.merge(X_train[X_train[i].str.contains('nan') == False], X_train) X_valid[i] = X_valid[i].astype(str) X_valid = pd.merge(X_valid[X_valid[i].str.contains('nan') == False], X_valid)
输出:
SaleCondition []
原因分析
问题核心出在循环中的pd.merge操作:
- 每次循环先过滤当前列不含'nan'的行得到子集,再与原
X_train执行内连接(merge默认行为)。内连接要求两行所有列值完全匹配,这会导致每次循环后X_train的行数急剧缩减。 - 循环从第一个列开始执行,经过多轮过滤+merge后,到
SaleCondition列时,X_train已经没有匹配的行,变成空DataFrame,因此打印该列得到空列表。 - 额外逻辑漏洞:
astype(str)会将原生NaN值转为字符串'nan',再用str.contains('nan')过滤的方式,会误过滤原数据中真实存在的字符串'nan'。
解决方案
方案1:替换错误过滤逻辑,删除冗余merge操作
直接过滤当前列为字符串'nan'的行,无需merge:
for i in X_train.columns: # 将列转为字符串,原生NaN会被转为'nan' X_train[i] = X_train[i].astype(str) # 过滤掉当前列值为'nan'的行 X_train = X_train[X_train[i] != 'nan'] # 同理处理X_valid X_valid[i] = X_valid[i].astype(str) X_valid = X_valid[X_valid[i] != 'nan']
方案2:高效批量处理(推荐)
如果目标是过滤掉所有含字符串'nan'的行,可批量处理避免循环迭代修改:
# 批量转换所有列为字符串 X_train = X_train.astype(str) # 过滤掉任意列值为'nan'的行 X_train = X_train[~(X_train == 'nan').any(axis=1)] # 同理处理X_valid X_valid = X_valid.astype(str) X_valid = X_valid[~(X_valid == 'nan').any(axis=1)]
方案3:优先处理原生NaN(更合理逻辑)
若原数据中的NaN是缺失值,建议直接用Pandas原生缺失值处理方法,而非转字符串过滤:
# 删除任意列含NaN的行 X_train = X_train.dropna() X_valid = X_valid.dropna() # 或按列逐一删除含NaN的行 for i in X_train.columns: X_train = X_train.dropna(subset=[i]) X_valid = X_valid.dropna(subset=[i])
内容的提问来源于stack exchange,提问作者Jinzu
相关产品推荐
相关产品推荐

