繁体   English   中英

pandas groupby将两列之间的差异求和,并获得每组的平均值

[英]pandas groupby sums differences between two columns and get the average for each group

我有以下df

year    code    col1   col2
2019    1       2      3
2019    1       3      5
2019    1       2      4
2018    2       1      4
2018    2       2      6

我想groupby df通过yearcode ,然后总和之间的差异col2col1平均在组大小的总和,然后,

df.apply(lambda row: (row['col_2'] - row['col_1']).mean(level=[0, 1]).reset_index(name='avg_num')

这段代码似乎是在计算差异的平均值,而不是将差异相加并除以组大小,因此该如何解决呢?

year    code    col1   col2    avg_num
2019    1       2      3       1.66
2019    1       3      5       1.66
2019    1       2      4       1.66
2018    2       1      4       3.5
2018    2       2      6       3.5

GroupBy.transform用于由聚合值填充的新列:

df['avg_num'] = (df.assign(avg_num=df.col2 - df.col1)
                   .groupby(['year', 'code'])['avg_num']
                   .transform('mean').round(2))
print (df)
   year  code  col1  col2  avg_num
0  2019     1     2     3     1.67
1  2019     1     3     5     1.67
2  2019     1     2     4     1.67
3  2018     2     1     4     3.50
4  2018     2     2     6     3.50

另一个没有assign解决方案,但是像df['year']df['code']一样需要将列传递给groupby

df['avg_num'] = ((df['col2'] - df['col1']).groupby([df['year'], df['code']])
                                          .transform('mean').round(2))
print (df)
   year  code  col1  col2  avg_num
0  2019     1     2     3     1.67
1  2019     1     3     5     1.67
2  2019     1     2     4     1.67
3  2018     2     1     4     3.50
4  2018     2     2     6     3.50

我们可以创建一个中间表来保存聚合值,然后将其重新连接到原始DataFrame。

aggs = df.assign(avg_num=df.col2 - df.col1) \
         .groupby(['year', 'code'], as_index=False)['avg_num'].mean().round(2)

print(aggs)

   year  code  avg_num
0  2018     2   3.50
1  2019     1   1.67

df.merge(aggs, how='inner', left_on=['year', 'code'], right_on=['year', 'code'])

   year  code  col1  col2  avg_num
0  2019     1     2     3   1.67
1  2019     1     3     5   1.67
2  2019     1     2     4   1.67
3  2018     2     1     4   3.50
4  2018     2     2     6   3.50
data = df.groupby(['year','code']).apply(lambda x: sum(list(abs(x.col2 - x.col1))) / len(list(abs(x.col2 - x.col1)))).reset_index().rename({0:'avg_num'},axis=1)

df.merge(data, on='year').drop('code_y', axis=1).rename({'code_x':'code'}, axis=1)

输出量

   year  code  col1  col2   avg_num
0  2019     1     2     3  1.666667
1  2019     1     3     5  1.666667
2  2019     1     2     4  1.666667
3  2018     2     1     4  3.500000
4  2018     2     2     6  3.500000

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM