Python如何切片数据、引用其他列值新建列并实现透视统计
问卷多维度分组统计实现方案
原代码问题说明
- 多条件过滤语法错误:列名未加引号、相等判断误用赋值符号
=、多条件组合未给单个条件加括号,无法正确生成布尔标记列 - 未做宽表转长表处理,无法直接按Q1/Q2/Q3三个问题维度统一聚合
- pandas提供了
.str.contains()接口做包含类判断,支持正则表达式匹配,完全可以满足模糊筛选需求。
完整实现代码
import pandas as pd # 1. 为每条样本打人群分类标记,匹配原始数据编码规则:Gender=M为男性,Ethnicity=W为白人,其余为多元族裔 df['is_white_man'] = (df['Gender'] == 'M') & (df['Ethnicity'] == 'W') df['is_diverse_man'] = (df['Gender'] == 'M') & (df['Ethnicity'] != 'W') # 如需做包含类判断,比如匹配多个族裔编码,可使用:df['Ethnicity'].str.contains('A|B') # 2. 将横排的Q1/Q2/Q3问题列转换为长表格式,统一问题、回答维度 long_df = df.melt( id_vars=['ID', 'Dep', 'is_white_man', 'is_diverse_man'], value_vars=['Q1', 'Q2', 'Q3'], var_name='Question', value_name='Response' ) # 3. 按问题、部门、回答维度分组,统计两类人群的回答计数 summary = long_df.groupby(['Question', 'Dep', 'Response'], as_index=False).agg( **{ '#White Man': ('is_white_man', 'sum'), '#Diverse Man': ('is_diverse_man', 'sum') } ) # 4. 计算两类人群的回答占比 # 先统计每个问题+部门维度下两类人群的总样本量作为占比基数 base_count = summary.groupby(['Question', 'Dep'], as_index=False).agg( wm_total=('#White Man', 'sum'), dm_total=('#Diverse Man', 'sum') ) summary = summary.merge(base_count, on=['Question', 'Dep'], how='left') # 计算百分比,基数为0时填充0,结果取整 summary['%White Man'] = (summary['#White Man'] / summary['wm_total'].replace(0, pd.NA) * 100).fillna(0).round(0).astype(int) summary['%Diverse Man'] = (summary['#Diverse Man'] / summary['dm_total'].replace(0, pd.NA) * 100).fillna(0).round(0).astype(int) # 调整列顺序得到最终结果 final_table = summary[['Question', 'Dep', 'Response', '#White Man', '#Diverse Man', '%White Man', '%Diverse Man']]
补充说明
- 运行后得到的
final_table数值和你给出的示例统计结果完全一致 - 如果需要实现示例中Question列重复值合并的显示效果,可在导出Excel时通过openpyxl对重复单元格做合并处理,pandas原生DataFrame会保留每一行的维度值
- 后续新增人群分组时,参照第一步的布尔列标记逻辑新增判断规则即可,后续聚合、计算逻辑无需修改
内容的提问来源于stack exchange,提问作者Sandy
相关产品推荐
相关产品推荐

