




本文介绍三种简洁高效的pandas方法,将问卷类yes/no分类数据按题目维度统计响应频次,并输出为“响应类型×题目”的标准宽格式汇总表,适用于报告生成与可视化前置处理。
在处理结构化问卷数据时,常需将原始的长形响应记录(每行一个客户、每列一个问题)转化为按响应类别(如 Yes/No)横向汇总的统计表。这种宽格式结果便于快速比较各题倾向性,也更适合作为图表输入或嵌入业务看板。
以下提供三种推荐方案,兼顾简洁性、通用性与可读性:
适用于严格只有 'Yes' 和 'No' 的场景,性能最优:
import pandas as pd
# 假设 df 为原始数据框
questions = df.filter(like='Question') # 提取所有 Question_* 列
yes_counts = questions.eq('Yes').sum() # 每列中 'Yes' 的数量(自动转布尔后求和)
no_counts = len(df) - yes_counts # 推导 'No' 数量
result = pd.DataFrame({'Yes': yes_counts, 'No': no_counts}).T
result.index.name = 'Response'✅ 优势:代码极简、执行快;❌ 局限:仅支持明确二值,无法扩展至多类(如 'Yes'/'No'/'Maybe')。
无需预设类别,自动识别全部唯一值,推荐作为默认选择:
melted = df.filter(like='Question').melt(var_name='Question', value_name='Response')
result = (melted.value_counts(['Response', 'Question'])
.unstack('Question', fill_value=0)
.rename_axis(index=None, columns=None))此方法先将问题列“熔解”为两列(Question, Response),再对组合频次计数,最后透视为宽表。自动覆盖所有响应值(包括意外空值或新增选项),且 fill_value=0 确保缺失组合补零。
语义最直观,适合强调“响应 × 题目”关系的场景:
stacked = df.filter(like='Question').stack() # 转为 Series,索引含 (client_id, question) result = pd.crosstab(stacked, stacked.index.get_level_values(1)) result.index.name = 'Response' result.columns.name = None

无论选择哪种方式,最终均可直接导出为 Excel 或传入 Seaborn/Matplotlib 进行热力图、堆叠柱状图等可视化,真正实现从原始数据到决策就绪报表的一站式转换。