使用Python进行分组加权中位数计算和聚合

3

我正在尝试根据多列查找一个列的加权中位数。以下是一个示例:

Date        |    Item    |   BetterPrice  |   TotalCost    |   Location
-------------------------------------------------------------------------
2022-03-01  |     AB     |       0        |      200       |      3
2022-03-01  |     AB     |       0        |      200       |      2
2022-03-01  |     AB     |       1        |      300       |      3
2022-03-01  |     AC     |       1        |      400       |      2
2022-04-01  |     AB     |       1        |      400       |      1
2022-04-01  |     AC     |       1        |      100       |      3
2022-04-01  |     AC     |       0        |      50        |      1

我想要找到Location列的加权中位数,并且我希望使用TotalCost列作为权重。 我想要使用聚合函数,因为我还想找到BetterPrice列的总和。

最初,我尝试使用wquantiles包中的weighted.median函数来完成任务,针对上述任务,我尝试了类似以下代码的操作:

import wquantiles
wm = lambda x: weighted.median(x , TotalCost)
df2 = df.groupby(['Date',  'Item']).agg({'BetterPrice': 'sum', "Location": wm}).reset_index()

很遗憾,这似乎不起作用,所以我想询问如何最好地完成这个任务,谢谢!
此外,这是一个数据框,可以复制上述问题(希望它足够详细)。
import pandas as pd

data={'Date':['2022-03-01','2022-03-01','2022-03-01','2022-03-01', '2022-04-01', '2022-04-01', '2022-04-01'],'Item':['AB','AB','AB','AC', 'AB', 'AC', 'AC'],'BetterPrice':[0,0,1,1, 1, 1, 0],'TotalCost':[200,200,300,400, 400, 100, 50],'Location':[3,2,3,2,1,3, 1]}


df=pd.DataFrame(data)

1
你好,欢迎来到这里。我相信这个答案会帮助你解决加权平均数的问题。在groupby之后,使用apply而不是aggc。另外,为什么你在BetterPrice列上使用size,而在文本中说你想要sum呢? - Ben.T
1
啊,抱歉,我现在已经用sum更新了我的代码。另外,我会尝试你提供的链接答案 - 实际上我可能几天前就尝试过了,因为它看起来非常熟悉,但我还是会再试一次以防万一。 - rightleftdownup313
1个回答

1

以下是一种方法。要获取加权中位数,您可以使用Location中TotalCost的 np.repeat 值的 np.median 。对于每个组进行此操作。然后将结果与组内另一列上的总和 concat 。

<code><code><code>gr = df.groupby(['Date',  'Item'])
res = pd.concat(
    [gr.apply(lambda x: np.median(np.repeat(x.Location, x.TotalCost))),
     gr['BetterPrice'].sum()],
    keys=['Loc_weigthed_median','BetterPrice_sum'],
    axis=1
).reset_index()
print(res)
#          Date Item  Loc_weighted_median  BetterPrice_sum
# 0  2022-03-01   AB                  3.0                1
# 1  2022-03-01   AC                  2.0                1
# 2  2022-04-01   AB                  1.0                1
# 3  2022-04-01   AC                  3.0                1
</code></code></code>

谢谢!我现在要尝试你的代码。不过我想知道,它是如何工作的呢?例如,在中位数中为什么要使用repeat(...)? - rightleftdownup313
1
@rightleftdownup313,numpy中没有加权中位数的实现,而且我也没有安装“wquantiles”。要获取中位数,您需要所有人口元素(而加权平均值不需要查看每个人口元素,计算略有不同)。无论如何,对于每个分组,您都需要使用其他列中给定的权重重复人口的每个元素,并获取中位数。 - Ben.T

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接