如何在Pandas DataFrame中统计元素频率并重构为指定表结构?
解决方法:将Pandas DataFrame转换为按points索引、variety为列的计数表
这需求用Pandas的几个内置方法就能轻松实现,我给你详细拆解下可行方案,先从示例数据开始:
第一步:准备示例数据
先还原你提供的数据集,方便复现测试:
import pandas as pd data = { 'points': [97, 67, 70, 97], 'variety': ['Chardonnay', 'Cabernet Sauvignon', 'Cabernet Sauvignon', 'Chardonnay'] } df = pd.DataFrame(data)
方案1:用pd.crosstab(最直接的交叉表方法)
这是最贴合你需求的工具,专门用来生成行/列维度的交叉统计:
# 生成以points为索引、variety为列的计数表 result_df = pd.crosstab(df['points'], df['variety'])
运行后得到的结果完全匹配你的要求:
variety Cabernet Sauvignon Chardonnay points 67 1 0 70 1 0 97 0 2
如果需要调整列的顺序(比如和你示例的顺序一致),可以手动指定列名:
result_df = result_df[['Chardonnay', 'Cabernet Sauvignon']]
方案2:用groupby + unstack
如果你更喜欢用分组的思路来实现,这个方法也很直观:
# 按points和variety分组统计数量,再将variety转为列,缺失值补0 result_df = df.groupby(['points', 'variety']).size().unstack(fill_value=0)
groupby(['points', 'variety']):按分数和品种分组.size():统计每组的出现次数.unstack(fill_value=0):把variety从行索引转成列,没有对应数据的位置填0
方案3:用pivot_table(更灵活的透视表方法)
透视表功能更强大,适合后续可能的扩展需求:
result_df = df.pivot_table( index='points', # 行索引为points columns='variety', # 列名为variety的唯一值 aggfunc='size', # 统计数量 fill_value=0 # 缺失值补0 )
额外补充:如果需要的是「出现频率(占比)」而非计数
如果你的需求是每个points下各品种的占比(而非绝对次数),只需要给crosstab加上normalize='index'参数:
# 生成各points下的品种占比表 freq_result = pd.crosstab(df['points'], df['variety'], normalize='index')
结果会是这样:
variety Cabernet Sauvignon Chardonnay points 67 1.0 0.0 70 1.0 0.0 97 0.0 1.0
内容的提问来源于stack exchange,提问作者Yneedtobeserious
相关产品推荐
相关产品推荐

