对来自 Pandas Dataframe 的行进行分组,其中列值在组中第一个值的 20% 以内

Grouping rows from Pandas Dataframe with column value within 20% of first value in group

假设我在下面有一个 Pandas 数据框:

ID 价值
0 1
1 2
2 1.2
3 1.6
4 1.5
5 1.4
6 1.1

我想在组的第一个元素的 20% 范围内对值进行分组。

ID
0 1 0
2 1.2 0
6 1.1 0
1 2 1
3 1.6 1
4 1.5 2
5 1.4 2

最好的方法是什么?

尝试:

df["group"] = np.nan
group = 0
while (m := df["group"].isna()).any():
    val = df.loc[m.idxmax(), "value"]
    df.loc[m & (np.abs(df["value"] - val) <= val * 0.2), "group"] = group
    group += 1

print(df.sort_values(by="group"))

打印:

   ID  value  group
0   0    1.0    0.0
2   2    1.2    0.0
6   6    1.1    0.0
1   1    2.0    1.0
3   3    1.6    1.0
4   4    1.5    2.0
5   5    1.4    2.0

这是另一个借助函数获取组的解决方案:

def getGroups(df, group):
    nullGroupMask = df['group'].isna()
    first = df.loc[nullGroupMask, 'value'].iat[0]
    df.loc[(df['value'] <= first+first*0.20) & (nullGroupMask), 'group'] = group
    return df

df['group'] = float('nan')
group = 0
while True:
    df = getGroups(df, group)
    group += 1
    if not df['group'].isna().any():
        break

df = df.astype({'group':int}).sort_values('group')

输出:

   ID  value  group
0   0    1.0      0
2   2    1.2      0
6   6    1.1      0
1   1    2.0      1
3   3    1.6      1
4   4    1.5      1
5   5    1.4      1