根据 panda df 到 sum/average 其他列的重复列值分组

Group by based on repeating column values of panda df to sum/average other columns

我有一个看起来像这样的 df:

    Activity    Count   angle_1frame_abs
87  11.2454 4   1.9863239600400613
88  14.3124 4   1.633204419481332
89  7.15621 4   1.7235925045363631
90  1.02232 4   1.4205234792290875
172 6.13389 1   1.9096280055821166
187 1.02232 3   1.7052938965382456
188 7.15621 3   1.708833899378485
189 2.04463 3   1.2728507985832682
233 4.08926 1   1.554572584797844
265 4.08926 2   1.512615236089327
266 5.11157 2   1.4850900583919704
281 6.13389 1   1.162132169753371
305 3.06694 2   2.3605660470439824
306 3.06694 2   1.5685525010916657
385 5.11157 2   1.6579646804948973
386 2.04463 2   2.121520877298791
407 5.11157 4   1.1528498264361269
408 12.2678 4   1.7986876725933032
409 9.20082 4   1.5502484587771188
410 2.04463 4   1.6302871732665316 

“计数”列有很多重复值,我想用它们来对 df 进行分组。

在上面的示例中,我将有 8 个组。

我很难将重复值作为单独的组。

我的最终目标是根据这些组对其他列进行平均 (Activity) 或求和 (angle_1frame_abs)。

我想要的输出是这样的(注意:activity 和 angle_1frames_abs 值是组合的):

Activity Count angle_1_frames_abs
9   4   1.7
6   1   1.9 
4   3   1.7
4   1   1.5
4   2   1.4
6   1   1.1
4   2   1.5
8   4   1.5

我一直在尝试类似的方法,但这只给了我基于“计数”列中唯一值的分组。

df.groupby(["Count"]).angle_1frame_abs.sum().reset_index()

您可以定义要保留在聚合函数中的每一列:

df.groupby(["Count"]).agg({k: ['sum', 'mean'] for k in df.columns}).reset_index()

此代码计算每组每一列的总和和平均值,因此这仅适用于只有数字列的数据框。
这是一个适用于小组的版本:

# firstly, create a helper column called "groups" (this col will signify
# when a value is changed in the Count column):
df['groups'] = None
group = 0
for i, j in df.iterrows():
    if i == 0:
        df.loc[i, 'groups'] = group
        valueBefore = df.loc[i, 'Count']
        continue
    if j.loc['Count'] != valueBefore:
        group += 1
    df.loc[i, 'groups'] = group
    valueBefore = df.loc[i, 'Count']
# then you can use it to groupby all other columns, i.e.:
df.groupby(["groups"]).agg({k: ['sum', 'mean'] for k in df.columns}).reset_index()

您可以使用 diff + ne + cumsum 创建群组。这个想法是检查值是否连续出现,如果不是,检查它在哪里中断。然后 cumsum 用于为组分配不同的数值:

groups = df['Count'].diff().ne(0).cumsum()

根据给定的输入,这将创建:

87     1
88     1
89     1
90     1
172    2
187    3
188    3
189    3
233    4
265    5
266    5
281    6
305    7
306    7
385    7
386    7
407    8
408    8
409    8
410    8

请注意,这会将“计数”分配给不同的组,即使它们相同,只要它们不连续即可。

然后您可以通过这些新组在 df 上使用 groupby。例如,每组“Activity”的平均值为:

out = df.groupby(groups)['Activity'].mean()

Count
1    8.434083
2    6.133890
3    3.407720
4    4.089260
5    4.600415
6    6.133890
7    3.322520
8    7.156205

此外,如果原始分组列不是数字(或数据类型的混合),另一种方法是使用 shift(感谢@StevenS):

df['count'].ne(df['count'].shift()).fillna(0).cumsum().astype(int)