pandas:计算分组平均值的差异

3

我有多个传感器的按月份和年份分类的传感器数据:

import pandas as pd
df = pd.DataFrame([
 ['A', 'Jan', 2015, 13], 
 ['A', 'Feb', 2015, 10], 
 ['A', 'Jan', 2016, 12], 
 ['A', 'Feb', 2016, 11], 
 ['B', 'Jan', 2015, 7],
 ['B', 'Feb', 2015, 8], 
 ['B', 'Jan', 2016, 4], 
 ['B', 'Feb', 2016, 9]
], columns = ['sensor', 'month', 'year', 'value'])

In [2]: df
Out[2]:
    sensor month  year  value
0      A   Jan  2015     13
1      A   Feb  2015     10
2      A   Jan  2016     12
3      A   Feb  2016     11
4      B   Jan  2015      7
5      B   Feb  2015      8
6      B   Jan  2016      4
7      B   Feb  2016      9

我使用groupby计算了每个传感器和每个月的平均值:

month_avg = df.groupby(['sensor', 'month']).mean()['value']

In [3]: month_avg
Out[3]:
sensor  month
A       Feb      10.5
        Jan      12.5
B       Feb       8.5
        Jan       5.5

现在我想要给df添加一列,其值为每月平均值与该行值之间的差异,类似于以下内容:
    sensor month  year  value  diff_from_avg
0      A   Jan  2015     13    1.5
1      A   Feb  2015     10    2.5
2      A   Jan  2016     12    0.5
3      A   Feb  2016     11    0.5
4      B   Jan  2015      7    2.5
5      B   Feb  2015      8    0.5
6      B   Jan  2016      4    -1.5
7      B   Feb  2016      9    -0.5

我尝试了类似的多索引 df avgs_by_month ,并尝试简单的减法,但效果不佳:

df = df.set_index(['sensor', 'month'])
df['diff_from_avg'] = month_avg - df.value

感谢您提供的任何建议。
谢谢。
3个回答

5

transform可以用来新建一列。

diff_from_avg=df.value - df.groupby(['sensor', 'month']).value.transform('mean')
df.assign(diff_from_avg=diff_from_avg)

  sensor month  year  value  diff_from_avg
0      A   Jan  2015     13            0.5
1      A   Feb  2015     10           -0.5
2      A   Jan  2016     12           -0.5
3      A   Feb  2016     11            0.5
4      B   Jan  2015      7            1.5
5      B   Feb  2015      8           -0.5
6      B   Jan  2016      4           -1.5
7      B   Feb  2016      9            0.5

1
哎呀!太快了!我应该开始使用“assign”了,这样就能更快地写出答案了! - juanpa.arrivillaga
这看起来很不错,但是我在第一行得到了一个没有帮助的错误:AttributeError: 'NoneType' object has no attribute 'transform'。你有什么想法吗? - robroc
@juanpa.arrivillaga 我使用 assign 是因为我不喜欢覆盖 df.. 特别是当我可能会计时操作的时候。 - piRSquared
回答自己的评论:使用方括号表示法时它可以工作: diff_from_avg=df.value - df.groupby(['sensor', 'month'])['value'].transform('mean') - robroc
@robroc 出于好奇,你使用的 pandas 版本是什么?pd.__version__ - piRSquared
显示剩余3条评论

2

尝试:

 df['diff_from_avg']=df.groupby(['sensor','month'])['value'].apply(lambda x: x-x.mean())
Out[18]:
  sensor month  year  value  diff_from_avg
0      A   Jan  2015     13            0.5
1      A   Feb  2015     10           -0.5
2      A   Jan  2016     12           -0.5
3      A   Feb  2016     11            0.5
4      B   Jan  2015      7            1.5
5      B   Feb  2015      8           -0.5
6      B   Jan  2016      4           -1.5
7      B   Feb  2016      9            0.5

0

您需要将DataFrame的索引设置与分组的Series保持一致,然后就可以直接进行减法操作:

df.set_index(['sensor','month'], inplace=True) df['diff'] = df['value'] - month_avg


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接