使用 diff 是正确的方法 - 只需将其与 gt 和 cumsum 结合使用,您就拥有了自己的群组。
我们的想法是对大于阈值的差异使用累积和。大于您的阈值的差异将变为True。相反,等于或低于您的阈值的差异将变为False。对布尔值进行累积求和将使差异等于或低于您的阈值不变,因此它们得到相同的组号。
max_distance = 1
df["group_diff"] = df.sort_values("val")\
.groupby("group_number")["val"]\
.diff()\
.gt(max_distance)\
.cumsum()
print(df)
group_number val group_diff
0 1 5 0
1 1 8 1
2 1 12 2
3 1 13 2
4 1 22 5
5 1 26 6
6 1 31 8
7 2 7 0
8 2 16 3
9 2 17 3
10 2 19 4
11 2 29 7
12 2 33 9
13 2 62 10
您现在可以在 group_number 和 group_diff 上使用 groupby 并查看结果组:
grouped = df.groupby(["group_number", "group_diff"])
print(grouped.groups)
{(1, 0): Int64Index([0], dtype='int64'),
(1, 1): Int64Index([1], dtype='int64'),
(1, 2): Int64Index([2, 3], dtype='int64'),
(1, 5): Int64Index([4], dtype='int64'),
(1, 6): Int64Index([5], dtype='int64'),
(1, 8): Int64Index([6], dtype='int64'),
(2, 0): Int64Index([7], dtype='int64'),
(2, 3): Int64Index([8, 9], dtype='int64'),
(2, 4): Int64Index([10], dtype='int64'),
(2, 7): Int64Index([11], dtype='int64'),
(2, 9): Int64Index([12], dtype='int64'),
(2, 10): Int64Index([13], dtype='int64')}
感谢@jezrael 提示避免使用新列以提高性能:
group_diff = df.sort_values("val")\
.groupby("group_number")["val"]\
.diff()\
.gt(max_distance)\
.cumsum()
grouped = df.groupby(["group_number", group_diff])