首页 > 解决方案 > 具有簇大小/密度变量和确切编号的二进制 numpy ndarray 中的聚类。零

问题描述

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

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

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

根据本页上的答案,制作了一个包含 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] 的集群:

聚集阵列

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

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

输出:

二进制聚集数组

这里的问题是,并非 50% 的值是 '1' 或 '0' 。

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

这是因为nlmpy.randomClusterNN首先生成不同聚类的函数,然后才对聚类进行二元重新分类。

我的问题是,是否可以以更快的方式生成二进制聚类景观,而无需首先在连续类中进行聚类,也无需使用 nlmpy 包?

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

非常感谢。

标签: pythonnumpybinaryclustered-index

解决方案


你可以或多或少地得到你想要的东西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)

输出:

在此处输入图像描述

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

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

如果我们以与以前相同的方式绘制这个不太密集的聚类,它会给出:

在此处输入图像描述


推荐阅读