有什么方法可以通过 numpy 对列表的接近数字进行分组吗?

Is there any way to group the close numbers of a list by numpy?

我有一个清单

x = [1,3,2,89,26,31,35,78,5,3,70]

我想要的是下面这样的东西:

[[1,2,3,5], [26,31,35], [70,78,89]]

是否可以从 python 中的整数列表中对最接近的整数元素进行分组?

对于预先指定的阈值 thr,如果每个整数与下一个最大整数的距离小于 thr,则假设一组整数“接近”。在这个定义下,我们可以用下面的函数将相近的数字分组在一起。

import numpy as np

def group(a,thr):
    x = np.sort(a)
    diff = x[1:]-x[:-1]
    gps = np.concatenate([[0],np.cumsum(diff>=thr)])
    return [x[gps==i] for i in range(gps[-1]+1)]

例如,group([1,3,2,89,26,31,35,78,5,3,70],20) returns

[array([1, 2, 3, 3, 5]), array([26, 31, 35]), array([70, 78, 89])]

我知道你的问题是专门针对 numpy 的,但正如 Ben 指出的那样,由你来决定阈值,这可能并不容易做到。

这对我来说听起来像是一个基本的 kmeans 练习,您可以在其中设置组数,然后让模型完成其余的工作。在此示例中,我选择了 3 个簇来匹配您的输出,但理想情况下,您可以使用 elbow method 之类的东西来选择最佳簇数,以便尽可能地分离组。

from sklearn.cluster import KMeans
import numpy as np
from itertools import groupby

x = [1,3,2,89,26,31,35,78,5,3,70]
x = sorted(x)

kmeans = KMeans(n_clusters=3, random_state=0).fit(np.reshape(x,(-1,1)))

[[i[0] for i in list(d)] for g,d in groupby(list(zip(x,kmeans.labels_)), key=lambda x: x[1])]

输出

[[1, 2, 3, 3, 5], [26, 31, 35], [70, 78, 89]]

编辑:

如果您想要一个功能:

def make_groups(data, n_groups):
    from sklearn.cluster import KMeans
    import numpy as np
    from itertools import groupby
    data = sorted(data)
    kmeans = KMeans(n_clusters=n_groups, random_state=0).fit(np.reshape(data,(-1,1)))

    return [[i[0] for i in list(d)] for g,d in groupby(list(zip(data,kmeans.labels_)), key=lambda x: x[1])]


x = [1,3,2,89,26,31,35,78,5,3,70]

make_groups(x, 3)