在python中,如何在数组中对这三个区域进行分组/集群?

2024-04-30 07:16:53 发布

您现在位置:Python中文网/ 问答频道 /正文

所以你有一个数组

1
2
3
60
70
80
100
220
230
250

为了更好地理解:

For better understanding

在python(v2.6)中,如何对数组中的三个区域进行分组/集群,因此在本例中得到三个数组,其中包含

[1 2 3] [60 70 80 100] [220 230 250]

背景:

y轴是频率,x轴是数字。这些数字是由其频率表示的十个最高振幅。我想从中创建三个离散的数字用于模式识别。可能会有更多的点,但所有这些点都是按相对较大的频率差分组的,如您在本例中看到的,大约在50到0之间,大约在100到220之间。请注意,什么是大变化什么是小变化,但是集群之间的差异与组/集群的元素之间的差异相比仍然是显著的。


Tags: 区域元素集群数字数组差异频率背景
3条回答

注意,如果x只表示索引,那么数据点实际上是一维的。可以使用Scipy的cluster.vq模块对点进行聚类,该模块实现了k-means算法。

>>> import numpy as np
>>> from scipy.cluster.vq import kmeans, vq
>>> y = np.array([1,2,3,60,70,80,100,220,230,250])
>>> codebook, _ = kmeans(y, 3)  # three clusters
>>> cluster_indices, _ = vq(y, codebook)
>>> cluster_indices
array([1, 1, 1, 0, 0, 0, 0, 2, 2, 2])

结果表明:前三个点形成簇1(任意标记),后四个点形成簇0,最后三个点形成簇2。根据索引对原始点进行分组留给读者作为练习。

有关Python中的更多集群算法,请查看scikit-learn

这是一个用python实现的简单算法,它可以检查一个值是否与一个集群的平均值相差太远(以标准偏差计):

from math import sqrt

def stat(lst):
    """Calculate mean and std deviation from the input list."""
    n = float(len(lst))
    mean = sum(lst) / n
    stdev = sqrt((sum(x*x for x in lst) / n) - (mean * mean)) 
    return mean, stdev

def parse(lst, n):
    cluster = []
    for i in lst:
        if len(cluster) <= 1:    # the first two values are going directly in
            cluster.append(i)
            continue

        mean,stdev = stat(cluster)
        if abs(mean - i) > n * stdev:    # check the "distance"
            yield cluster
            cluster[:] = []    # reset cluster to the empty list

        cluster.append(i)
    yield cluster           # yield the last cluster

这将使用5 < n < 9返回您在示例中期望的结果:

>>> array = [1, 2, 3, 60, 70, 80, 100, 220, 230, 250]
>>> for cluster in parse(array, 7):
...     print(cluster)
[1, 2, 3]
[60, 70, 80, 100]
[220, 230, 250]

我想你需要一个很好但很简单的算法。

如果知道需要N个簇,则可以获取(排序)输入列表的连续成员之间的差异(delta)。E、 g.在纽比:

 deltas = diff( sorted(input) )

然后你可以把你的剪贴画放在你发现N-2最大差异的地方。

如果你不知道N是什么,事情就更棘手了。在这里,当你看到一个大于一定大小的三角洲时,你可以放置截断。这将是一个手动调整的参数,虽然不是很好,但可能对您来说已经足够好了。

相关问题 更多 >