分组依据,应用函数并插入具有相应值的新列

时间:2019-10-02 18:08:46

标签: python pandas numpy

我正在尝试为某些特定用户群计算加权平均值,但似乎无法获取输出并与之形成新的列。

我尝试了groupby并应用函数,但似乎无法将其转换回新列

 df = pd.DataFrame('cohort_size': [10,15,20,25,20,15],
'retention' : [0.3,0.2,0.4,0.5,0.6,0.5],
'nth_interval' : [1,1,1,7,7,7])

df.groupby('nth_interval').apply(lambda x: np.average(x['retention'], weights=x['cohort_size']))

我得到的输出是一个序列,但我真正想要的是获取这些单独的加权平均值,并将其放回数据框中作为新列,其中每个列的值对应于nth_interval

3 个答案:

答案 0 :(得分:1)

IIUC,您在寻找这个吗?

df.merge(df.groupby('nth_interval').apply(lambda x: np.average(x['retention'],
                                                   weights=x['cohort_size']))
                                   .rename('wgted_avg').reset_index(), 
         on='nth_interval')

输出:

   cohort_size  retention  nth_interval  wgted_avg
0           10        0.3             1   0.311111
1           15        0.2             1   0.311111
2           20        0.4             1   0.311111
3           25        0.5             7   0.533333
4           20        0.6             7   0.533333
5           15        0.5             7   0.533333

答案 1 :(得分:1)

您可以进行合并:

df.merge(df.groupby('nth_interval')
           .apply(lambda x: np.average(x['retention'], weights=x['cohort_size']))
           .to_frame(name='average'),
         on='nth_interval')

或地图:

s = df.groupby('nth_interval')
               .apply(lambda x: np.average(x['retention'], weights=x['cohort_size']))

df['average'] = df['nth_interval'].map(s)

输出:

   cohort_size  retention  nth_interval   average
0           10        0.3             1  0.311111
1           15        0.2             1  0.311111
2           20        0.4             1  0.311111
3           25        0.5             7  0.533333
4           20        0.6             7  0.533333
5           15        0.5             7  0.533333

或者您也可以手动进行计算:

df['average'] = (df['retention'].mul(df['cohort_size'])
                      .groupby(df['nth_interval'])
                      .transform('sum')
                      .div(df['cohort_size'].groupby(df['nth_interval'])
                                            .transform('sum'))
                 )

答案 2 :(得分:0)

您可以保存自己的变换合并。对于大数据,通常希望避免这种情况。

df['weighted_avg'] = df.groupby('nth_interval')['retention']
    .transform(lambda x: np.average(x, weights=df.loc[x.index, 'cohort_size']))

关于.loc的工作方式。 .loc是获取数据子集的一种方法。您可以为其指定标签,索引或布尔索引。第一个参数用于行,第二个参数用于列。在这里,我使用保留序列组的索引来获取相应的cohort_size。基本上我是在叫df.loc[[0, 1, 2], 'cohort_size']df.loc[[3, 4, 5], 'cohort_size']