python 二维数组中的集群或组二进制数据

python cluster or group binary data in 2 dimensional array

我正在尝试为我的机器人识别星际争霸 2 地图中 minerals/gas 的区域。下图显示了我的二维数组图,其中 1 表示矿物或气体块。

仔细观察,您会发现有 4 个我想识别的簇。

我试过使用:

from scipy.ndimage import measurements
lw, num = measurements.label(map)

(map) 是一个 64,64 数组,其中有一个 mineral/gas 补丁。

这会找到 21 个簇,因为在 4 个簇中,有一些空白。

另外,我不知道我在获取数组时要查找多少个簇。我正在查看连接组件标签,但我看不到只要 1 离 3 或 4 个位置元素远,就可以将它们视为连接的方法。我只见过4个或8个连接的方法。

我应该如何解决这个问题?

这实际上是一整 class 个问题,clustering algorithms

我建议从迭代 k-means 风格的方法开始,例如 here。您可以 运行 它的大小为 2 - n(或者您认为您会找到多少个聚类),然后使用 P 值来衡量聚类的置信度。 (即,P 值应该非常 high/unsure 当 运行ning k-means 有 2 个集群时,当地图上明显有 3 个集群时,它们应该是 low/sure 如果你 运行 具有 3 个簇的 k-means)

祝你好运!

你的集群看起来很明显是分开的,所以只要把它们放大一点来融合它们的部分。例如,您可以使用 scipy.ndimage.morphology.binary_dilation:

from scipy.ndimage import measurements, morphology
import numpy as np

# create mock data
data = """

  1111 1                     1
       1                    1
        1              11111



 111111 111
           1
           1

"""

data = np.array(data.split('\n'))
data = data.view('U1').reshape(len(data), -1) == '1'
# blow it up a bit
data = np.kron(data, np.ones((2, 2), dtype=int))


# "algorithm" starts here
grow = morphology.binary_dilation(data, structure=np.ones((5, 5), dtype=int)
lbl, npatches = measurements.label(grow)
lbl[data==0] = 0
# end of algorithm


# show
res = '\n'.join(lbl.astype('U1').view(f"U{lbl.shape[1]}").ravel()).replace('0', ' ')
print(res)

输出:

        11111111  11                                          22
        11111111  11                                          22
                  11                                        22  
                  11                                        22  
                    11                            22222222      
                    11                            22222222      






      3333333333    333333                                      
      3333333333    333333                                      
                          33                                    
                          33                                    
                          33  3333                              
                          33  3333                              

如果它不能直接作用于您的实际数据,请尝试使用不同的结构元素或简单地扩大乘数。

这对于使用单link 层次聚类或 DBSCAN 进行聚类来说是微不足道的。只需使用足够小的距离阈值来加入近处的矿物,并分离远处的矿物。可能 5 个单元格工作正常。