问题描述
df = pd.DataFrame.from_dict(dict([('A',[2000,1000,2509,2145]),('A_Weight',[37,47,33,16]),('B',[2100,1500,2000,1600]),('B_weights',[17,21,6,2]),('C',[2500,1400,2300]),('C_weights',[5,35,40]),('D',[0,1600,2100,2000]),('D_weights',32,10,5])]))
我希望加权平均值位于名为“WA”的新列中,但每次尝试时它都会显示 NaN
Desired Dataframe 将是一个具有以下值的新列,例如:
我使用的公式 (((A * A_weight)+(B * b_weight)+(C * C_weight)+(D * D_weight)) / sum(all weights)
df['WA'] = [2071.19,1323.70,2363.20,2214.60 ]
谢谢
解决方法
一种直接而简单的方法如下:
(由于您的权重列名称的命名不一致,例如一些带有“s”而一些没有,一些带有大写字母“W”而一些带有小写字母“w”,因此对列进行分组是不方便的,例如.filter()
)
df['WA'] = ( (df['A'] * df['A_Weight']) + (df['B'] * df['B_weights']) + (df['C'] * df['C_weights']) + (df['D'] * df['D_weights']) ) / (df['A_Weight'] + df['B_weights'] + df['C_weights'] + df['D_weights'])
结果:
print(df)
A A_Weight B B_weights C C_weights D D_weights WA
0 2000 37 2100 17 2500 5 0 0 2071.186441
1 1000 47 1500 21 1400 35 1600 32 1323.703704
2 2509 33 2000 6 0 0 2100 10 2363.204082
3 2145 16 1600 2 2300 40 2000 5 2214.603175
,
不那么直接的方式:
- 通过
str.split
按前缀对列进行分组 - 通过
groupby prod
获取列式乘积 - 在轴 1 上使用
sum
获取乘积的行式总和。 -
filter
+sum
在轴 1 上得到“权重”列的总和 - 将组乘积总和除以权重总和。
df['WA'] = (
df.groupby(df.columns.str.split('_').str[0],axis=1).prod().sum(axis=1)
/ df.filter(regex='_[wW]eight(s)?$').sum(axis=1)
)
A A_Weight B B_weights C C_weights D D_weights WA
0 2000 37 2100 17 2500 5 0 0 2071.186441
1 1000 47 1500 21 1400 35 1600 32 1323.703704
2 2509 33 2000 6 0 0 2100 10 2363.204082
3 2145 16 1600 2 2300 40 2000 5 2214.603175