You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

尝试过的无效代码

  1. 单个分组固定值赋值:
titanic_df2.loc[(titanic_df2.Title =='Mr') & (titanic_df2['Age'].isnull()), 'Age'] = 14
  1. 错误的分组批量赋值:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 19:27:01