我一直在尝试从每个组的值中进行分组和二进制,并获得平均值,但我似乎找不到一种直接的方法。
数据帧:
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个不同的代码,我想分组,然后bin,并获得该bin的平均值,以具有如下数据帧:
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),但没有给我我想要的结果,而且我仍然需要垃圾箱的平均值。
编辑注释:不是所有组的大小都相同,也不是所有组在天数上都是均匀分布的,例如,一些组在20天内结束,这打破了直线式除以一个数字的能力。也许这只能通过分组,然后循环遍历每个组来创建存储箱来解决。
任何帮助都是非常感谢的。
发布于 2021-09-28 00:46:20
尝试使用agg的groupby
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'})发布于 2021-09-28 01:09:18
在每个组中生成回收站的一个好方法是使用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.0https://stackoverflow.com/questions/69354519
复制相似问题