You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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 111253267
Location 218234770
Location 320342857
Location 123354054

需要合并所有报表后生成如下格式的透视表(包含各地点、各月份的苹果占比和胡萝卜占比):

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 19:20:47