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

基于DataFrame同行多列生成符合条件的性别计数器

基于DataFrame的年龄组匹配性别统计

问题背景

我有一个大型DataFrame,包含多个孩子的具体年龄、性别,以及一些二进制列,示例如下:

kid1_age    kid2_age    kid3_age   kid1_gndr  kid2_gndr    kid3_gndr ..  age_1825   age_1217  ..
 index
   0      18           12         nan       Male       nan          nan           1          1 
   1      21           17         nan       Female     Male          nan           1          0 
   2      15           13          1        Female     Female        Male          0          1 

(注:原示例中存在重复列名kid1_gndr,已修正为kid3_gndr保证逻辑合理)

其中age_1825代表年龄在18-25岁的孩子,age_1217代表年龄在12-17岁的孩子,以此类推。二进制列值为1表示对应年龄组的孩子正确填写了数据。

目标是生成Male和Female统计列,统计二进制列值为1且年龄匹配对应组的孩子的性别数量,最终结果示例:

kid1_age  kid2_age   kid3_age  kid1_gndr  kid2_gndr  kid3_gndr  age_1825  age_1217      Male      Female
18           12       nan       Male       nan        nan         1         1           2          0
21           17       nan       Female     Male        nan         1         0           0          1
15           13       1         Female     Female      Male        0         1           0          2

统计逻辑要求:

  1. 识别正确填写数据的年龄组(二进制列值为1的列)
  2. 找出年龄落在该组的孩子
  3. 获取这些孩子的性别
  4. 累计对应性别的数量

我是Python新手,不知道怎么实现,求帮助。


解决方案

步骤1:定义年龄组与区间的映射

先把所有年龄组列名对应的年龄区间整理成字典,方便后续匹配:

age_group_mapping = {
    'age_1825': (18, 25),
    'age_1217': (12, 17),
    # 其他年龄组按此格式补充即可
}

步骤2:筛选孩子的年龄和性别列

从DataFrame中提取所有孩子的年龄列和性别列,确保一一对应:

# 筛选所有以"_age"结尾的列(孩子年龄)
age_cols = [col for col in df.columns if col.endswith('_age')]
# 筛选所有以"_gndr"结尾的列(孩子性别)
gender_cols = [col for col in df.columns if col.endswith('_gndr')]

步骤3:编写逐行统计函数

写一个函数处理DataFrame的每一行,按规则统计符合条件的性别数量:

def count_genders(row):
    male_count = 0
    female_count = 0
    
    # 遍历每个需要统计的年龄组
    for group_col, (min_age, max_age) in age_group_mapping.items():
        # 仅处理二进制值为1的年龄组
        if row[group_col] == 1:
            # 逐个检查每个孩子的年龄和性别
            for age_col, gender_col in zip(age_cols, gender_cols):
                kid_age = row[age_col]
                kid_gender = row[gender_col]
                
                # 跳过空值数据
                if pd.isna(kid_age) or pd.isna(kid_gender):
                    continue
                
                # 判断年龄是否在当前组区间内
                if min_age <= kid_age <= max_age:
                    # 累计对应性别计数
                    if kid_gender == 'Male':
                        male_count += 1
                    elif kid_gender == 'Female':
                        female_count += 1
    # 返回统计结果
    return pd.Series([male_count, female_count], index=['Male', 'Female'])

步骤4:应用函数生成统计列

将函数应用到原DataFrame的每一行,合并统计结果:

import pandas as pd

# 假设你的原始DataFrame名为df
stats = df.apply(count_genders, axis=1)
# 把统计列合并到原DataFrame
result_df = pd.concat([df, stats], axis=1)

完整可运行示例

import pandas as pd

# 构造示例数据(修正原重复列名问题)
data = {
    'kid1_age': [18, 21, 15],
    'kid2_age': [12, 17, 13],
    'kid3_age': [pd.NA, pd.NA, 1],
    'kid1_gndr': ['Male', 'Female', 'Female'],
    'kid2_gndr': [pd.NA, 'Male', 'Female'],
    'kid3_gndr': [pd.NA, pd.NA, 'Male'],
    'age_1825': [1, 1, 0],
    'age_1217': [1, 0, 1]
}
df = pd.DataFrame(data)

# 定义年龄组映射
age_group_mapping = {
    'age_1825': (18, 25),
    'age_1217': (12, 17)
}

# 筛选年龄和性别列
age_cols = [col for col in df.columns if col.endswith('_age')]
gender_cols = [col for col in df.columns if col.endswith('_gndr')]

# 统计函数
def count_genders(row):
    male_count = 0
    female_count = 0
    for group_col, (min_age, max_age) in age_group_mapping.items():
        if row[group_col] == 1:
            for age_col, gender_col in zip(age_cols, gender_cols):
                kid_age = row[age_col]
                kid_gender = row[gender_col]
                if pd.isna(kid_age) or pd.isna(kid_gender):
                    continue
                if min_age <= kid_age <= max_age:
                    if kid_gender == 'Male':
                        male_count +=1
                    elif kid_gender == 'Female':
                        female_count +=1
    return pd.Series([male_count, female_count], index=['Male', 'Female'])

# 生成统计列并合并
stats = df.apply(count_genders, axis=1)
result_df = pd.concat([df, stats], axis=1)

# 打印结果
print(result_df)

注意事项

  • 若有更多年龄组,只需在age_group_mapping中补充对应的列名和区间
  • 确保孩子的年龄列与性别列严格一一对应(如kid1_age对应kid1_gndr)
  • 处理超大型DataFrame时,apply效率可能偏低,后续可学习向量化操作优化,但此方法对新手更直观易懂

内容的提问来源于stack exchange,提问作者hao

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 12:22:46