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

如何在列名不同时将一个Pandas透视表(DataFrame)除以另一个?

我想要实现的目标

我正在使用pandas计算一些透视表,希望将其中一个除以另一个。
以下是一个虚构数据示例,我有某类商品的销售数据,想要计算总销售额(美元)、销售数量、单价等指标。
另一个场景是计算加权平均值,最后一步需要除以权重。
数据带有多重索引(multi-indices),因为这是按不同分类切片分析的结果(例如,在伦敦和纽约分别售出了多少高质量和低质量的小部件)。

最小可复现示例

在以下示例中,我创建了维度为7×8的DataFrame piv_all_sales:

  • 7行:2个地区 × 3种产品 + 1行总计
  • 8列:2个指标(总销售额gross sales、净销售额net sales) ×(3种品质(low、medium、high) + 1列总计)

piv_all_sales的样式如下:
piv_all_sales样式

piv_count统计销售商品的数量,维度为7×4:
piv_count样式

我想要将前者除以后者,但DataFrame.div()方法无法生效——推测是因为两个DataFrame的列名不同。
另一个复杂点在于piv_all_sales有8列,而piv_count只有4列

import numpy as np
import pandas as pd

rng = np.random.default_rng(seed=42)
df=pd.DataFrame()
df['region'] = np.repeat(['USA','Canada'],12)
df['product'] = np.tile(['apples','strawberries','bananas'],8)
df['quality'] = np.repeat(['high','medium','low'],8)

df['net sales'] = rng.integers(low=0, high=100, size=24)
df['gross sales'] = rng.integers(low=50, high=150, size=24)
df['# items sold'] = rng.integers(low=1, high=20, size=24)


piv_net_sales = pd.pivot_table(data=df,
                           values=['net sales'],
                           index=['region','product'],
                           columns=['quality'],
                           aggfunc='sum',
                           margins=True)

piv_all_sales = pd.pivot_table(data=df,
                           values=['net sales','gross sales'],
                           index=['region','product'],
                           columns=['quality'],
                           aggfunc='sum',
                           margins=True)

piv_count = pd.pivot_table(data=df,
                           values=['# items sold'],
                           index=['region','product'],
                           columns=['quality'],
                           aggfunc='sum',
                           margins=True)

我已尝试的方法

我不知道如何将7×8的DataFrame除以7×4的DataFrame。
因此我先尝试将7×4的DataFrame(仅包含净销售额的piv_net_sales)除以7×4的piv_count,但两种方式都无效:

out1 = piv_net_sales / piv_count
out2 = piv_net_sales.div(piv_count)

推测是因为pandas会查找同名列,但未找到?
两种方式都生成了全为NaN的7×8 DataFrame。

部分低效解决方案

唯一可行的方法是将每个DataFrame转换为numpy数组,再进行除法运算。这样就无需考虑列名不同的问题,但存在以下缺点:

  • 方法非常繁琐且不优雅,因为我需要将DataFrame转换为numpy数组,之后还要重新创建带有正确索引的DataFrame
  • 我仍不知道如何将7×8的DataFrame除以7×4的DataFrame;或许可以将7×8的数组拆分为两个7×4的数组,分别计算后再合并?
    该方法可行,但不够优雅且效率低下
    out3 = piv_net_sales.to_numpy() / piv_count.to_numpy()
    

类似问题

我找到了一些类似问题,例如:
How to divide two Pandas Pivoted Tables
但我无法将这些答案适配到我的场景中。


内容的提问来源于stack exchange,提问作者Pythonista anonymous

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 17:09:58