Python:按Title列分组,用对应年龄范围随机值替换Age列NaN
按Title分组用对应年龄范围随机数填充Age列NaN值
需求说明
根据Title列的分组,用对应分组年龄范围内的随机数值替换Age列中的NaN值。已知每个Title组有对应年龄范围(如Mrs组最大年龄76,Mr组最大67),共9个Title分组。
示例数据
简化样本
Age Title 34.5 Mr 47.0 Mrs 62.0 Mr 27.0 Mr 22.0 Mrs 14.0 Mr 30.0 Miss 26.0 Mr 18.0 Mrs 21.0 Mr NaN Mr 46.0 Mr
完整DataFrame示例
PassengerId Survived Pclass Sex Age SibSp Parch Ticket Fare Embarked Title 0 892 0 3 male 34.5 0 0 330911 7.8292 Q Mr 1 893 1 3 female 47.0 1 0 363272 7.0000 S Mrs 2 894 0 2 male 62.0 0 0 240276 9.6875 Q Mr 3 895 0 3 male 27.0 0 0 315154 8.6625 S Mr 4 896 1 3 female 22.0 1 1 3101298 12.2875 S Mrs ... ... ... ... ... ... ... ... ... ... ... ... 413 1305 0 3 male NaN 0 0 A.5. 3236 8.0500 S Mr 414 1306 1 1 female 39.0 0 0 PC 17758 108.9000 C Dona 415 1307 0 3 male 38.5 0 0 SOTON/O.Q. 3101262 7.2500 S Mr 416 1308 0 3 male NaN 0 0 359309 8.0500 S Mr 417 1309 0 3 male 5.0 1 1 2668 22.3583 C Master
尝试过的无效代码
- 单个分组固定值赋值:
titanic_df2.loc[(titanic_df2.Title =='Mr') & (titanic_df2['Age'].isnull()), 'Age'] = 14
- 错误的分组批量赋值:
g = titanic_df2.groupby('Title', group_keys=False) titanic_df2.loc[(g & (titanic_df2['Age'].isnull())), 'Age'] = random.randint(g.min(),g.max())
解决方案
方案1:使用已知的年龄范围字典
如果已经明确每个Title的年龄范围,直接定义字典批量填充:
import numpy as np # 替换为实际已知的9个Title年龄范围 title_age_ranges = { 'Mr': (14, 67), 'Mrs': (18, 76), 'Miss': (0, 30), 'Master': (0, 10), 'Dona': (30, 60), # 补充剩余4个Title的范围 } # 遍历每个分组填充NaN for title, (min_age, max_age) in title_age_ranges.items(): mask = (titanic_df2['Title'] == title) & titanic_df2['Age'].isna() # 生成对应数量的随机整数,若需浮点用np.random.uniform titanic_df2.loc[mask, 'Age'] = np.random.randint(min_age, max_age + 1, size=mask.sum())
方案2:从数据中自动计算分组年龄范围
如果没有预先知道范围,直接从现有非NaN数据中提取每个Title的年龄极值:
import numpy as np # 计算每个Title的Age最小、最大值(过滤掉无有效Age的分组) title_age_stats = titanic_df2.groupby('Title')['Age'].agg(['min', 'max']).dropna() # 遍历分组填充 for title, row in title_age_stats.iterrows(): min_age, max_age = row['min'], row['max'] mask = (titanic_df2['Title'] == title) & titanic_df2['Age'].isna() titanic_df2.loc[mask, 'Age'] = np.random.randint(min_age, max_age + 1, size=mask.sum())
无效代码问题说明
- 第一段代码仅能给单个分组赋值固定值,无法满足随机范围需求,且效率低下。
- 第二段代码存在两处错误:groupby对象不能直接与布尔索引做逻辑运算;
random.randint只能生成单个整数,无法批量生成对应行数的随机数。
内容的提问来源于stack exchange,提问作者Nasim Al Goni Shourav
相关产品推荐
相关产品推荐

