如何在Pandas中按列索引并结合另一列聚合生成统计宽表?
问题描述
我有一个包含学生编号(Student)、所在州(State)、年龄(Age)的Pandas DataFrame,需要生成一个新的DataFrame,按州和年龄汇总学生信息:以州为行、年龄为列,统计每个州各年龄段的学生数量。
原始DataFrame示例:
| Student | State | Age |
|---|---|---|
| 1 | California | 13 |
| 2 | California | 14 |
| 3 | Colorado | 12 |
| ... | ... | ... |
期望生成的结果DataFrame:
| State | 9 | 10 | 11 | 12 | 13 | 14 |
|---|---|---|---|---|---|---|
| California | 0 | 0 | 0 | 0 | 1 | 1 |
| Colorado | 0 | 1 | 2 | 3 | 2 | 0 |
| ... | ... | ... | ... | ... | ... | ... |
实际数据包含数千行,需要高效实现该需求。
解决方案
优先推荐:使用Pandas内置交叉表/透视表(高效无迭代)
Pandas提供的内置方法底层基于C实现,比Python手动迭代快得多,完全适配大数据量场景。
方法1:pd.crosstab 直接生成交叉表
这是最贴合需求的方案,一步完成统计:
import pandas as pd # 假设原始数据存储在DataFrame df中 result = pd.crosstab(df['State'], df['Age']) # 确保包含所有目标年龄段(示例为9-14岁),无数据的填充0 target_ages = list(range(9, 15)) result = result.reindex(columns=target_ages, fill_value=0)
方法2:pivot_table 灵活透视统计
如果需要自定义聚合逻辑,可使用透视表:
result = df.pivot_table( index='State', columns='Age', values='Student', # 任意非空列均可,这里选学生编号 aggfunc='count', # 统计数量 fill_value=0 # 空值填充0 ) # 确保包含所有目标年龄段 target_ages = list(range(9, 15)) result = result.reindex(columns=target_ages, fill_value=0)
若必须使用迭代(不推荐,效率低)
如果业务场景特殊需要手动迭代,可按以下方式实现,但大数据量下性能会显著下降:
import pandas as pd # 获取所有唯一州和目标年龄段 unique_states = df['State'].unique() target_ages = list(range(9, 15)) # 初始化结果DataFrame,填充默认值0 result = pd.DataFrame(index=unique_states, columns=target_ages).fillna(0) # 迭代每个州,统计各年龄段人数 for state in unique_states: # 筛选当前州的数据 state_df = df[df['State'] == state] # 统计当前州各年龄的学生数 age_count = state_df['Age'].value_counts() # 填充到结果表中 for age in target_ages: result.loc[state, age] = age_count.get(age, 0) # 可选:将State从索引转为列 result = result.reset_index().rename(columns={'index': 'State'})
内容的提问来源于stack exchange,提问作者Mateo Castaño Sierra
相关产品推荐
相关产品推荐

