我有一个数据框,我需要对距离不超过1的元素进行分组。 例如,如果这是我的df:
group_number val
0 1 5
1 1 8
2 1 12
3 1 13
4 1 22
5 1 26
6 1 31
7 2 7
8 2 16
9 2 17
10 2 19
11 2 29
12 2 33
13 2 62
所以我需要将group_number
和val
分组,其中val
的值小于或等于1.
因此,在此示例中,行2
和3
会组合在一起,而行8
和9
也会组合在一起。
我尝试使用diff或相关功能,但我没弄明白。
任何帮助将不胜感激!
答案 0 :(得分:2)
使用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])
答案 1 :(得分:0)
所以您想将 val
中差值为 1 或更接近的值组合在一起?
你可以做的一件事:
假设您有十进制数,您可以按四舍五入的值对它们进行分组,这意味着您可以使用 df.round
将它们分组到最接近的指定小数位,例如将它们四舍五入到最接近的整数:
df.groupby(df["val"].round(0))
因为你有整数,你可以做的是将 val 除以 2,所以以前相差 1 的值现在相差 0.5。现在你用上面的函数把它们四舍五入到最接近的整数,你就可以这样分组了!
顺便说一句,我不认为这是一个完整的答案,它只是对该主题的一个建议,任何发现这个问题的人都会很感兴趣