根据 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)
我有一个看起来像这样的 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)