【问题标题】:weighted average aggregation on multiple columns of dfdf 多列的加权平均聚合
【发布时间】:2021-07-12 12:55:42
【问题描述】:

我正在尝试计算数据框中多列的加权平均值。 这是我的数据样本

Group Year Month Weight(kg) Nitrogen Calcium
A 2020 01 10000 10 70
A 2020 01 15000 4 78
A 2021 05 12000 5 66
A 2021 05 10000 8 54
B 2021 08 14000 10 90
C 2021 08 50000 20 92
C 2021 08 40000 10 95

我想要的结果如下所示:

我尝试过的: 我可以使用此函数获得单个列的正确加权平均值: (类似于:link

def wavg(df, value, weight):
    d = df[value]
    w = df[weight]
    try:
        return (d * w).sum() / w.sum()
    except ZeroDivisionError:
        return d.mean()

我可以将此函数应用于我的 df 的单个列:

df2 = df.groupby(["Group", "year", "month"]).apply(wavg, "Calcium", "Weight(kg").to_frame()

(不要介意不同的值,它们对我笔记本中的数据是正确的)

明显的问题是这个函数只适用于一列,而我有几十列。因此我尝试了一个 for 循环:

column_list=[]
for column in df.columns:
  column_list.append(df.groupby(["Group", "year", "month"]).apply(wavg, column, "Weight(kg").to_frame())

它正确地计算了值,但列被放置在彼此之上而不是彼此相邻。他们还错过了一个有用的列名:

如何调整我的代码以返回所需的 df?

【问题讨论】:

  • 尝试连接它们(根据您的需要在任一轴上):df=pd.concat(column_list)df=pd.concat(column_list,axis=1)
  • 谢谢,pd.concat (column_list, axis=1) 确实有效。我确实得到了一个需要扁平化的多索引,但这是朝着正确方向迈出的一步。
  • 嗨!以下任何一个答案是否有效?如果是这样并且如果您愿意,您可以考虑accepting 其中之一向其他人发出问题已解决的信号。如果没有,您可以提供反馈,以便改进(或完全删除)

标签: python pandas aggregate weighted-average


【解决方案1】:

用于多列工作和避免删除列进行分组的更改功能正在转换为MultiIndex

def wavg(x, value, weight):
    d = x[value]
    w = x[weight]
    try:
        return (d.mul(w, axis=0)).div(w.sum())
    except ZeroDivisionError:
        return d.mean()

#columns used for groupby
groups = ["Group", "Year", "Month"]
#processing all another columns
cols = df.columns.difference(groups + ["Weight(kg)"], sort=False)

#create index and processing all columns by variable cols
df1 = (df.set_index(groups)
         .groupby(level=groups)
         .apply(wavg, cols, "Weight(kg)")
         .reset_index())
print (df2)
  Group  Year  Month    Calcium   Nitrogen
0     A  2020      1  28.000000   4.000000
1     A  2020      1  46.800000   2.400000
2     A  2021      5  36.000000   2.727273
3     A  2021      5  24.545455   3.636364
4     B  2021      8  90.000000  10.000000
5     C  2021      8  51.111111  11.111111
6     C  2021      8  42.222222   4.444444

【讨论】:

  • 感谢您的反馈。代码几乎可以工作,但在创建 df2 期间出现以下错误: ValueError: cannot join with nooverlap index names。我该如何解决这个问题?
  • @brenda89 - 如果删除 .reset_index() 它工作吗?
  • @brenda89 - 什么是变量cols?像cols = df.columns.difference(["Group", "Year", "Month"], sort=False) 这样的所有未用于 groupby 的列如何工作?
【解决方案2】:

通过concat()reset_index() 尝试:

df=pd.concat(column_list,axis=1).reset_index()

您可以在此处进行更改:

column_list=[]
for column in df.columns:
  column_list.append(df.groupby(["Group", "year", "month"]).apply(wavg, column, "Weight(kg").reset_index())

#Finally:

df=pd.concat(column_list,axis=1)

【讨论】:

  • 可能的解决方案,但就性能而言,最好只使用所有列一次,而不是单独使用每一列然后使用concat
  • @jezrael 明白了,先生 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-31
  • 2021-09-03
  • 2017-04-13
  • 2019-04-29
相关资源
最近更新 更多