如何使用Pandas生成包含占比的多月份透视表?
解决月度报表合并与占比透视表生成问题
问题背景
你有若干份月度报表,每份结构如下:
data = [['Location 1', 11, 25, 32, 67], ['Location2', 18, 23, 47, 70], ['Location3', 20, 34, 28, 57], ['Location 1', 23, 35, 40, 54]] df = pd.DataFrame(data, columns=['Location', '# of Apples', '# of Fruits', '# of Carrots', '# of Vegetables'])
对应表格:
| Location | # of Apples | # of Fruits | # of Carrots | # of Vegetables |
|---|---|---|---|---|
| Location 1 | 11 | 25 | 32 | 67 |
| Location 2 | 18 | 23 | 47 | 70 |
| Location 3 | 20 | 34 | 28 | 57 |
| Location 1 | 23 | 35 | 40 | 54 |
需要合并所有报表后生成如下格式的透视表(包含各地点、各月份的苹果占比和胡萝卜占比):
January February Location % of Apples % of Carrots % of Apples % of Carrots Location 1 56.7% 59.5% 48.7% 53.8% Location 2 78.3% 67.1% 73.5% 70.8% Location 3 58.8% 74.1% 59.2% 72.3%
你尝试过用pd.pivot_table生成了正确的月份横向格式,但不会计算占比;也算出了正确的占比数值,但格式不符合要求。另外,原始报表不含月份字段,读取时会添加文件名并替换为对应月份。
解决方案
步骤1:合并报表并添加月份字段
假设你有包含所有报表路径的列表file_paths,每个文件名对应月份(如january.csv对应January),读取时添加月份列:
import pandas as pd import numpy as np # 示例文件路径,替换为你的实际路径 file_paths = ["january.csv", "february.csv"] dfs = [] for path in file_paths: # 从文件名提取月份名并格式化 month = path.split(".")[0].capitalize() df = pd.read_csv(path) df["Month"] = month dfs.append(df) # 合并所有月度报表 combined_df = pd.concat(dfs, ignore_index=True)
步骤2:分组聚合并计算占比
先按月份和地点求和,再计算两个占比指标:
# 按月份、地点分组求和 grouped = combined_df.groupby(["Month", "Location"]).sum().reset_index() # 计算苹果占比(苹果数量/水果数量*100) grouped["% of Apples"] = grouped["# of Apples"] / grouped["# of Fruits"] * 100 # 计算胡萝卜占比(胡萝卜数量/蔬菜数量*100) grouped["% of Carrots"] = grouped["# of Carrots"] / grouped["# of Vegetables"] * 100
步骤3:构建目标格式的透视表
通过pivot生成多层列结构,调整列顺序匹配目标格式:
# 构建透视表:行=地点,列=(月份, 占比类型) pivot_result = grouped.pivot( index="Location", columns="Month", values=["% of Apples", "% of Carrots"] ) # 交换列层级,让每个月份下先显示苹果占比、再显示胡萝卜占比 pivot_result = pivot_result.swaplevel(axis=1).sort_index(axis=1)
步骤4:格式化百分比显示
将数值转换为带%的字符串,保留一位小数:
pivot_result = pivot_result.applymap(lambda x: f"{x:.1f}%")
此时pivot_result的结构和格式完全匹配你的需求。
内容的提问来源于stack exchange,提问作者be84
相关产品推荐
相关产品推荐

