使用 pandas 数据框计算加权平均值
Calculate weighted average with pandas dataframe
我有以下 pandas 数据框:
data_df = pd.DataFrame({'ind':['la','p','la','la','p','g','g','la'],
'dist':[10.,5.,7.,8.,7.,2.,5.,3.],
'diff':[0.54,3.2,8.6,7.2,2.1,1.,3.5,4.5],
'cas':[1.,2.,3.,4.,5.,6.,7.,8.]})
即
cas diff dist ind
0 1 0.54 10 la
1 2 3.20 5 p
2 3 8.60 7 la
3 4 7.20 8 la
4 5 2.10 7 p
5 6 1.00 2 g
6 7 3.50 5 g
7 8 4.50 3 la
我需要计算权重在 'dist' 列中的所有列的加权平均值,并将值按 'ind' 分组。
例如 'ind'='la' 和 'diff' 列:
((10*0.54)+(8.60*7)+(7.20*8)+(4.50*3))/(10+7+8+3) = 4.882143
我要得到的结果如下
cas diff
ind
g 6.714286 2.785714
la 3.107143 4.882143
p 3.750000 2.558333
将每个列的每个值乘以'dist'列中的相应值,将结果与相同的'ind'相加,然后将结果除以所有的总和'dist' 个值对应相同的 ind。
我认为这将是数据框 'groupby' 方法完成的一项简单任务,但实际上它有点棘手。
有人可以帮我吗?
您可以通过使用transform
:
获得组内归一化权重
>>> df['weight'] = df['dist'] / df.groupby('ind')['dist'].transform('sum')
>>> df['weight']
0 0.357143
1 0.416667
2 0.250000
3 0.285714
4 0.583333
5 0.285714
6 0.714286
7 0.107143
Name: weight, dtype: float64
然后,你只需要将这些权重乘以数值,然后求和:
>>> df['wcas'], df['wdiff'] = (df[n] * df['weight'] for n in ('cas', 'diff'))
>>> df.groupby('ind')[['wcas', 'wdiff']].sum()
wcas wdiff
ind
g 6.714286 2.785714
la 3.107143 4.882143
p 3.750000 2.558333
编辑:使用就地突变:
>>> backup = df.copy() # make a backup copy to mutate in place
>>> cols = df.columns[:2] # cas, diff
>>> df[cols] = df['weight'].values[:, None] * df[cols]
>>> df.groupby('ind')[cols].sum()
cas diff
ind
g 6.714286 2.785714
la 3.107143 4.882143
p 3.750000 2.558333
我有以下 pandas 数据框:
data_df = pd.DataFrame({'ind':['la','p','la','la','p','g','g','la'],
'dist':[10.,5.,7.,8.,7.,2.,5.,3.],
'diff':[0.54,3.2,8.6,7.2,2.1,1.,3.5,4.5],
'cas':[1.,2.,3.,4.,5.,6.,7.,8.]})
即
cas diff dist ind
0 1 0.54 10 la
1 2 3.20 5 p
2 3 8.60 7 la
3 4 7.20 8 la
4 5 2.10 7 p
5 6 1.00 2 g
6 7 3.50 5 g
7 8 4.50 3 la
我需要计算权重在 'dist' 列中的所有列的加权平均值,并将值按 'ind' 分组。
例如 'ind'='la' 和 'diff' 列:
((10*0.54)+(8.60*7)+(7.20*8)+(4.50*3))/(10+7+8+3) = 4.882143
我要得到的结果如下
cas diff
ind
g 6.714286 2.785714
la 3.107143 4.882143
p 3.750000 2.558333
将每个列的每个值乘以'dist'列中的相应值,将结果与相同的'ind'相加,然后将结果除以所有的总和'dist' 个值对应相同的 ind。
我认为这将是数据框 'groupby' 方法完成的一项简单任务,但实际上它有点棘手。
有人可以帮我吗?
您可以通过使用transform
:
>>> df['weight'] = df['dist'] / df.groupby('ind')['dist'].transform('sum')
>>> df['weight']
0 0.357143
1 0.416667
2 0.250000
3 0.285714
4 0.583333
5 0.285714
6 0.714286
7 0.107143
Name: weight, dtype: float64
然后,你只需要将这些权重乘以数值,然后求和:
>>> df['wcas'], df['wdiff'] = (df[n] * df['weight'] for n in ('cas', 'diff'))
>>> df.groupby('ind')[['wcas', 'wdiff']].sum()
wcas wdiff
ind
g 6.714286 2.785714
la 3.107143 4.882143
p 3.750000 2.558333
编辑:使用就地突变:
>>> backup = df.copy() # make a backup copy to mutate in place
>>> cols = df.columns[:2] # cas, diff
>>> df[cols] = df['weight'].values[:, None] * df[cols]
>>> df.groupby('ind')[cols].sum()
cas diff
ind
g 6.714286 2.785714
la 3.107143 4.882143
p 3.750000 2.558333