填充NaN值函数异常:原有Age值被全部置为NaN问题排查
问题原因及修复方案
核心问题
你的agemaking函数只在Age为NaN的情况下返回了填充值,但对于非NaN的Age,函数没有任何返回语句——Python中无return的函数默认返回None,而pandas会把None解析为NaN,这就是原有非缺失值全部变成NaN的根源。
修复步骤
- 修正
agemaking逻辑,确保所有分支都有返回值:将else: return Age移到外层if的外面,保证非NaN的Age直接返回原值。 - 避免操作全局变量
train_titanic,让preprocessing函数处理传入的df参数,保证函数封装性。 - 可选优化:用
groupby+transform替代apply,代码更简洁且效率更高。
修复后的代码
方案1:修正原apply逻辑
import pandas as pd def preprocessing(df): # 计算各分组的中位数 median_male_3 = df[(df["Sex"] == "male") & (df["Pclass"] == 3)]["Age"].median() median_male_2 = df[(df["Sex"] == "male") & (df["Pclass"] == 2)]["Age"].median() median_male_1 = df[(df["Sex"] == "male") & (df["Pclass"] == 1)]["Age"].median() median_female_3 = df[(df["Sex"] == "female") & (df["Pclass"] == 3)]["Age"].median() median_female_2 = df[(df["Sex"] == "female") & (df["Pclass"] == 2)]["Age"].median() median_female_1 = df[(df["Sex"] == "female") & (df["Pclass"] == 1)]["Age"].median() def agemaking(para): Age = para[0] bookclass = para[1] sex = para[2] if pd.isnull(Age): if bookclass == 3 and sex == "male": return median_male_3 elif bookclass == 2 and sex == "male": return median_male_2 elif bookclass == 1 and sex == "male": return median_male_1 elif bookclass == 3 and sex == "female": return median_female_3 elif bookclass == 2 and sex == "female": return median_female_2 elif bookclass == 1 and sex == "female": return median_female_1 else: return Age # 非NaN情况直接返回原值 return Age # 处理传入的df,而非全局变量 df['Age'] = df[['Age','Pclass','Sex']].apply(agemaking, axis=1) return df # 调用示例 # train_titanic = preprocessing(train_titanic)
方案2:更高效的groupby+transform实现
import pandas as pd def preprocessing(df): # 按Sex和Pclass分组,自动用每组中位数填充Age缺失值 df['Age'] = df.groupby(['Sex', 'Pclass'])['Age'].transform( lambda x: x.fillna(x.median()) ) return df # 调用示例 # train_titanic = preprocessing(train_titanic)
该方案无需手动计算每个分组的中位数,pandas会自动完成分组与填充,代码更简洁,处理大数据集时效率也更高。
内容的提问来源于stack exchange,提问作者Simon
相关产品推荐
相关产品推荐

