Pandas:调查结果DataFrame浓缩及转换最优方法咨询
嘿,这个问题问到点子上了!咱们结合调查数据的常见场景,一步步拆解来看:
核心选择:Pivot 还是 Groupby?
首先得明确你的目标格式是什么——这直接决定了工具的选择:
- 如果是想把长格式数据(每行是单个用户对单个问题的回答)转成宽格式(每行对应一个用户,列是各个问题的回答),那Pivot(或pivot_table)是最直接高效的选择。它就是专门用来做这种「行列转换」的,代码简洁,逻辑清晰,完全不用绕弯子。
- 如果你的需求是按维度做聚合统计(比如统计每个问题的「Yes」占比、不同群体的回答差异),那Groupby才是主场。但要是只是单纯的格式重塑,Pivot绝对是首选。
把'Yes'替换成布尔值的优势?必须有!
换成True/False布尔值的好处真的不少:
- 内存更省:布尔值在Pandas里只占1字节,比字符串(至少占几个字节)节省很多,数据量越大优势越明显。
- 计算更顺手:后续统计的时候,直接用
.sum()就能算出每个用户的「Yes」数量,.mean()直接得到问题的同意率,完全不用额外写字符串匹配的条件,代码干净又高效。 - 逻辑更直观:布尔测试本身就是Pandas里处理这类问题的常规操作,直接把回答转成布尔值,后续的条件判断、过滤都会更顺畅,减少冗余代码。
具体实现示例(附代码)
先假设你的原始调查DataFrame是常见的长格式(比如这样):
import pandas as pd # 模拟调查数据:user_id=用户ID,question=问题,response=回答 df = pd.DataFrame({ 'user_id': [1,1,2,2,3], 'question': ['Q1', 'Q2', 'Q1', 'Q2', 'Q1'], 'response': ['Yes', 'No', 'Yes', 'Yes', 'No'] })
第一步:把'Yes'/'No'转成布尔值
两种高效写法任选:
# 写法1:字典映射(适合有更多回答类型的场景) df['response'] = df['response'].map({'Yes': True, 'No': False}) # 写法2:直接布尔判断(更简洁,仅针对Yes/No场景) df['response'] = df['response'] == 'Yes'
第二步:用Pivot转成宽格式
如果要得到「每个用户对应所有问题的布尔回答」:
wide_df = df.pivot(index='user_id', columns='question', values='response')
如果存在同一个用户对同一个问题的重复回答(比如多次提交),可以用pivot_table指定聚合方式(比如取第一个有效回答,或者按多数投票):
# 取第一个回答作为最终结果 wide_df = df.pivot_table(index='user_id', columns='question', values='response', aggfunc='first')
什么时候用Groupby?
举个例子,如果你要统计每个问题的同意人数和同意率:
question_stats = df.groupby('question')['response'].agg(['sum', 'count']) question_stats['agree_rate'] = question_stats['sum'] / question_stats['count']
一句话总结
- 单纯格式重塑(长转宽):选
pivot/pivot_table,一步到位。 - 分组统计分析:用
groupby,灵活处理各类聚合需求。 - 替换'Yes'为布尔值:强烈推荐,既省内存又让后续操作更丝滑。
内容的提问来源于stack exchange,提问作者Boreal Coder
相关产品推荐
相关产品推荐

