使用Pandas GroupBy实现品牌-产品统计、百分比转换及系数调整
解决方案步骤
1. 生成带行列总计的交叉统计表(计数)
先构建原始数据集,通过groupby统计品牌-产品组合的出现频次,再转换为宽表并添加行、列总计:
import pandas as pd # 创建原始数据 data = { '品牌': ['Nike', 'Nike', 'Adidas', 'Adidas', 'Adidas', 'Flight'], '产品': ['鞋', '袜子', '鞋', '鞋', '袜子', '短裤'] } df = pd.DataFrame(data) # 统计品牌-产品组合的出现次数 count_table = df.groupby(['品牌', '产品']).size().unstack(fill_value=0) # 添加行总计(各品牌的总次数) count_table['行总计'] = count_table.sum(axis=1) # 添加列总计(各产品的总次数) count_table.loc['列总计'] = count_table.sum(axis=0) print(count_table)
运行后得到的计数表:
短裤 鞋 袜子 行总计 品牌 Adidas 0 2 1 3 Flight 1 0 0 1 Nike 0 1 1 2 列总计 1 3 2 6
2. 转换为基于列总计的百分比
提取核心数据列,除以对应列的总计值得到占比,再格式化为百分比,最后补全行、列总计:
# 提取需计算百分比的部分(排除行总计列和列总计行) percent_data = count_table.drop('行总计', axis=1).drop('列总计', axis=0) # 计算列占比:每个单元格除以该列的总计值 percent_table = percent_data.div(count_table.loc['列总计'].drop('行总计'), axis=1) # 格式化为保留两位小数的百分比 percent_table = percent_table.applymap(lambda x: f"{x:.2%}") # 重新添加行总计(各产品占比之和) percent_table['行总计'] = percent_table.sum(axis=1) # 添加列总计(各品牌在该产品的占比之和) percent_table.loc['列总计'] = percent_table.sum(axis=0) print(percent_table)
运行结果:
短裤 鞋 袜子 行总计 品牌 Adidas 0.00% 66.67% 50.00% 116.67% Flight 100.00% 0.00% 0.00% 100.00% Nike 0.00% 33.33% 50.00% 83.33% 列总计 100.00% 100.00% 100.00% 300.00%
注:行总计的和超过100%是不同产品占比的累加结果,若不需要可保留原始计数的行总计,按需调整即可。
3. 对所有单元格数值乘以调整系数
完全可以实现,分两种场景处理:
- 针对计数表:直接对数值列乘以系数
adjust_factor = 0.75 adjusted_count_table = count_table.multiply(adjust_factor) print(adjusted_count_table)
- 针对百分比表:先把百分比转回小数,乘以系数后再重新格式化为百分比
# 百分比转回小数 percent_decimal = percent_table.applymap(lambda x: float(x.strip('%'))/100) # 乘以调整系数 adjusted_percent_decimal = percent_decimal.multiply(adjust_factor) # 重新转为百分比格式 adjusted_percent_table = adjusted_percent_decimal.applymap(lambda x: f"{x:.2%}") print(adjusted_percent_table)
内容的提问来源于stack exchange,提问作者zen
相关产品推荐
相关产品推荐

