在具有群集大小/密度变量且精确编号的二进制numpy ndarray中进行群集。零

时间:2018-11-23 14:16:41

标签: python numpy binary clustered-index

我是编程新手,希望有人可以帮助我解决我遇到的特定问题。

我想在两种情况下在100x100二进制numpy ndarray中形成簇:

  1. 我要指定值为零和一的像素数。
  2. 我想要一个输入变量,使我可以形成更大或更小的集群。

借助this页上的答案,我制作了一个具有300个零和700个零的ndarray。

> import numpy as np

> N=1000 
> K=300 

> arr=[0] * K + [1] * (N-K)
> np.random.shuffle(arr)
> arr1=np.resize(arr,(100,100))

然后,我想实现一个聚类算法,该算法允许我指定某种度量聚类密度或聚类大小的方法。

我查看了scipy.ndimage软件包,但似乎找不到任何有用的东西。

编辑:为了使我的问题更清楚,以前我使用的是软件包nlmpy,该软件包使用numpy制作表示虚拟景观的数组。

它是通过生成一个连续数组,其连续值在[0-1]之间,并在像素子集上使用“ 4-邻域”分类来实现的。像素聚类后,它使用插值函数将其余像素分配给一个聚类。

例如,以60%的像素组成簇:

import nlmpy
nRow=100
nCol=100
arr=nlmpy.randomClusterNN(nRow, nCol, 0.60, n='4-neighbourhood', mask=None)

这将为簇提供[0-1]范围内的值:

Clustered array

然后,我使用nlmpy的内置函数将该输出重新分类为二进制ndarray。 例如,50%的像素需要具有值'1'和50%的值'0'。

arrBinair= nlmpy.classifyArray(arr, [0.50, 0.50])

输出:

Binary clustered array

这里的问题是,并非精确地有50%的值是“ 1”或“ 0”。

print(arrBinair==1).sum()
output: 3023.0

这是因为nlmpy.randomClusterNN函数首先创建了不同的集群,然后才对集群进行二进制重新分类。

我的问题是,是否可以以更快的方式生成二进制集群格局,而无需先在连续类中集群并且不使用nlmpy包?

我希望这是足够的信息?还是我需要将功能发布到nlmpy软件包的“幕后”?我很犹豫,因为有很多代码。

非常感谢。

1 个答案:

答案 0 :(得分:0)

您可以使用sklearn.cluster.DBSCAN或多或少地获得想要的东西:

from matplotlib import pyplot as plt
import numpy as np
from sklearn.cluster import DBSCAN

def randones(shape, n, dtype=None):
    arr = np.zeros(shape, dtype=dtype)
    arr.flat[np.random.choice(arr.size, size=n, replace=False)] = 1
    return arr

def cluster(arr, *args, **kwargs):
    data = np.array(arr.nonzero()).T
    c = DBSCAN(*args, **kwargs)
    c.fit(data)
    return data, c

# generate random data
shape = (100, 100)
n = 300
arr = randones(shape, n)

# perform clustering
data, c = cluster(arr, eps=6, min_samples=4)

# plot the clusters in different colors
colors = [('C%d' % (i%10)) if i > -1 else 'k' for i in c.labels_]
fig = plt.figure(figsize=(8,8))
ax = fig.gca()
ax.scatter(*data.T, c=colors)

输出:

enter image description here

集群中的最小点数由min_samples参数定义。您可以通过旋转eps参数(该参数定义  群集中两点之间的最大距离)。例如,您可以通过增加eps来识别较大,密度较小的群集:

# perform clustering
data, c = cluster(arr, eps=8, min_samples=4)

如果我们以与以前相同的方式绘制此密度较低的聚类,则得出:

enter image description here