Pandas groupby、bin 和 average
Posted
技术标签:
【中文标题】Pandas groupby、bin 和 average【英文标题】:Pandas groupby, bin and average 【发布时间】:2021-11-20 01:40:55 【问题描述】:我一直在尝试从每个组的值中对分组和 bin 进行分组并获得平均值,但我似乎找不到直接的方法。
数据框:
code1 code2 code3 day amount
abc1 xyz1 123 1 25
abc1 xyz1 123 2 5
abc1 xyz1 123 3 15
. . . . .
. . . . .
abc1 xyz1 123 20 10
abc2 xyz1 456 1 4
. . . . .
. . . . .
abc10 xyz5 890 21 5
我想对 3 个不同的代码进行分组,然后分箱并获得该箱的平均值,以获得这样的数据框:
code1 code2 code3 day amount
abc1 xyz1 123 [1-3] 15
abc1 xyz1 123 [4-6] 13
abc1 xyz1 123 [7-9] 17
. . . . .
. . . . .
abc10 xyz5 890 [19-21] 18
我尝试过:
df(['code1', 'code2', 'code3'])[day].apply(pd.cut, bins=7)
但没有给我想要的结果,而且我仍然需要 bin 的平均值。
编辑说明:并非所有组的大小都相同,并且并非所有组的天数分布均等,例如,某些组以 20 结束,例如,破坏了直接除以数字的能力。也许这只能通过分组来解决,然后遍历每个组以创建垃圾箱。
感谢任何帮助。
【问题讨论】:
所有组都可以使用所有日期吗?还是每个组的日垃圾箱都不一样? 是的,所有组的日期范围不相等,有些组较早/较晚完成的 bin 大小不同,所以最后一个 bin 可能是 [19-20] 并且也不同不同的运行需要 bin 大小。 【参考方案1】:试试groupby
和agg
:
df.groupby(df.index // 3).agg(k: ('last' if k != 'day' else lambda x: f'[min(x)-max(x)]') for k in df.columns)
或者只指定列名更好:
df.groupby(df.index // 3).agg('code1': 'last', 'code2': 'last', 'code3': 'last', 'day': lambda x: f'[min(x)-max(x)]', 'amount': 'last')
【讨论】:
如果所有组的大小都相同,这肯定有效,但不幸的是,我的数据集并非如此。我会用这些细节更新我的问题。【参考方案2】:在每个组中生成您的垃圾箱的好方法是groupby.transform
:
>>> binned_days = df.groupby(['code1', 'code2', 'code3'])['day'].transform(pd.cut, bins=7, precision=0, right=False)
>>> binned_days
0 [1.0, 4.0)
1 [1.0, 4.0)
2 [1.0, 4.0)
5 [17.0, 20.0)
6 [0.9999, 1.0001)
9 [20.997, 21.003)
Name: day, dtype: interval
符号与您的垃圾箱略有不同,[1.0, 4.0)
而不是[1, 3]
- 但含义相同。事实上,由于数据类型是区间,因此很容易转换,即使您应该使用 .apply
while the .interval
accessor does not exist yet:
>>> binned_days = binned_days.apply(lambda iv: pd.Interval(int(iv.left), int(iv.right), closed='both'))
>>> binned_days
0 [1, 4]
1 [1, 4]
2 [1, 4]
5 [17, 20]
6 [0, 1]
9 [20, 21]
Name: day, dtype: interval
现在我们可以使用列和这些天的定义来计算平均值:
>>> df.groupby(['code1', 'code2', 'code3', binned_days])[['amount']].mean().reset_index()
code1 code2 code3 day amount
0 abc1 xyz1 123 [1, 4] 15.0
1 abc1 xyz1 123 [17, 20] 10.0
2 abc10 xyz5 890 [20, 21] 5.0
3 abc2 xyz1 456 [0, 1] 4.0
【讨论】:
以上是关于Pandas groupby、bin 和 average的主要内容,如果未能解决你的问题,请参考以下文章