df 多列的加权平均聚合
weighted average aggregation on multiple columns of df
我正在尝试计算数据框中多列的加权平均值。
这是我的数据样本
组
年
月份
体重(公斤)
氮气
钙
一个
2020
01
10000
10
70
一个
2020
01
15000
4
78
一个
2021
05
12000
5
66
一个
2021
05
10000
8
54
B
2021
08
14000
10
90
C
2021
08
50000
20
92
C
2021
08
40000
10
95
我想要的结果看起来像这样:
我尝试过的:
我可以使用此函数获得单个列的正确加权平均值:
(类似于:)
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())
它计算的值是正确的,但是列放在彼此的顶部而不是彼此相邻。他们还错过了一个有用的列名:
我怎样才能使我的代码适应 return 所需的 df?
用于多列工作和避免删除列进行分组的更改函数正在转换为 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
尝试通过 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)
我正在尝试计算数据框中多列的加权平均值。 这是我的数据样本
组 | 年 | 月份 | 体重(公斤) | 氮气 | 钙 |
---|---|---|---|---|---|
一个 | 2020 | 01 | 10000 | 10 | 70 |
一个 | 2020 | 01 | 15000 | 4 | 78 |
一个 | 2021 | 05 | 12000 | 5 | 66 |
一个 | 2021 | 05 | 10000 | 8 | 54 |
B | 2021 | 08 | 14000 | 10 | 90 |
C | 2021 | 08 | 50000 | 20 | 92 |
C | 2021 | 08 | 40000 | 10 | 95 |
我想要的结果看起来像这样:
我尝试过的:
我可以使用此函数获得单个列的正确加权平均值:
(类似于:
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())
它计算的值是正确的,但是列放在彼此的顶部而不是彼此相邻。他们还错过了一个有用的列名:
我怎样才能使我的代码适应 return 所需的 df?
用于多列工作和避免删除列进行分组的更改函数正在转换为 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
尝试通过 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)