簡體   English   中英

如何在2D numpy數組中找到簇大小?

[英]How to find cluster sizes in 2D numpy array?

我的問題如下,

我有一個2D numpy數組填充0和1,具有吸收邊界條件(所有外部元素都是0),例如:

[[0 0 0 0 0 0 0 0 0 0]
 [0 0 1 0 0 0 0 0 0 0]
 [0 0 1 0 1 0 0 0 1 0]
 [0 0 0 0 0 0 1 0 1 0]
 [0 0 0 0 0 0 1 0 0 0]
 [0 0 0 0 1 0 1 0 0 0]
 [0 0 0 0 0 1 1 0 0 0]
 [0 0 0 1 0 1 0 0 0 0]
 [0 0 0 0 1 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]]

我想創建一個函數,將此數組及其線性維L作為輸入參數(在本例中為L = 10),並返回此數組的簇大小列表。

“簇”是指陣列中元素1的孤立組

如果數組元素[i] [j]的所有鄰居都是零,則它是孤立的,並且它的鄰居是元素:

[i+1][j]
[i-1][j]
[i][j+1]
[i][j-1]

所以在之前的數組中我們有7個大小的簇(2,1,2,6,1,1,1)

我試圖通過創建兩個函數來完成這個任務,第一個是遞歸函數:

def clust_size(array,i,j):

    count = 0

    if array[i][j] == 1:

        array[i][j] = 0

        if array[i-1][j] == 1:

            count += 1
            array[i-1][j] = 0
            clust_size(array,i-1,j)

        elif array[i][j-1] == 1:

            count += 1
            array[i-1][j] = 0
            clust_size(array,i,j-1)

        elif array[i+1][j] == 1:

            count += 1
            array[i-1][j] =  0
            clust_size(array,i+1,j)

        elif array[i][j+1] == 1:

            count += 1
            array[i-1][j] = 0
            clust_size(array,i,j+1)

    return count+1         

它應該返回一個集群的大小。 每次函數找到一個等於1的數組元素時,它會增加計數器“count”的值,並將元素的值更改為0,這樣每個“1”元素只計算一次。 如果該元素的一個鄰居等於1,則該函數在該元素上調用自身。

第二個功能是:

def clust_list(array,L):

    sizes_list = []

    for i in range(1,L-1):
        for i in range(1,L-1):

           count = clust_size(array,i,j)

           sizes_list.append(count)

    return sizes_list

它應該返回包含簇大小的列表。 for循環從1迭代到L-1,因為所有外部元素都是0。

這不起作用,我看不出錯誤在哪里......

我想知道是否有更簡單的方法來做到這一點。

這似乎是一個滲透問題。 如果你安裝了scipy,以下鏈接有你的答案。

http://dragly.org/2013/03/25/working-with-percolation-clusters-in-python/

from pylab import *
from scipy.ndimage import measurements

z2 = array([[0,0,0,0,0,0,0,0,0,0],
    [0,0,1,0,0,0,0,0,0,0],
    [0,0,1,0,1,0,0,0,1,0],
    [0,0,0,0,0,0,1,0,1,0],
    [0,0,0,0,0,0,1,0,0,0],
    [0,0,0,0,1,0,1,0,0,0],
    [0,0,0,0,0,1,1,0,0,0],
    [0,0,0,1,0,1,0,0,0,0],
    [0,0,0,0,1,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0]])

這將識別集群:

lw, num = measurements.label(z2)
print lw
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
   [0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
   [0, 0, 1, 0, 2, 0, 0, 0, 3, 0],
   [0, 0, 0, 0, 0, 0, 4, 0, 3, 0],
   [0, 0, 0, 0, 0, 0, 4, 0, 0, 0],
   [0, 0, 0, 0, 5, 0, 4, 0, 0, 0],
   [0, 0, 0, 0, 0, 4, 4, 0, 0, 0],
   [0, 0, 0, 6, 0, 4, 0, 0, 0, 0],
   [0, 0, 0, 0, 7, 0, 0, 0, 0, 0],
   [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

以下將計算他們的面積。

area = measurements.sum(z2, lw, index=arange(lw.max() + 1))
print area
[ 0.  2.  1.  2.  6.  1.  1.  1.]

這給出了你的期望,雖然我認為你會有一個由8個成員通過眼睛滲透的集群。

我覺得你找到“集群”的問題,基本上是基於4連接在二進制映像中找到連接組件(值為0或1)的問題。 您可以在此Wikipedia頁面中看到幾種算法來識別連接的組件(或您定義它們的“簇”):

http://en.wikipedia.org/wiki/Connected-component_labeling

標記連接的組件或“群集”后,您可以輕松找到所需的任何信息,包括區域,相對位置或您可能需要的任何其他信息。

我相信你的方式幾乎是正確的,除非你在遞歸調用你的函數clust_size時一遍又一遍地初始化變量count 我會將count變量添加到clust_size的輸入參數中,並在count = 0嵌套for循環中為每次第一次調用重新初始化它。

像這樣,你會調用clust_size總是像count=clust_size(array, i ,j, count)我還沒有測試過,但在我看來它應該可行。

希望能幫助到你。

如果將其轉換為字符串則是一個相對簡單的問題

import numpy as np                                       
arr=np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0,],           
              [0, 0, 1, 0, 0, 0, 0, 0, 0, 0,],           
              [0, 0, 1, 1, 1, 1, 1, 1, 1, 0,],   #modified        
              [0, 0, 0, 0, 0, 0, 1, 0, 1, 0,],           
              [0, 0, 0, 0, 0, 0, 1, 0, 0, 0,],           
              [0, 0, 0, 0, 1, 0, 1, 0, 0, 0,],           
              [0, 0, 0, 0, 0, 1, 1, 0, 0, 0,],           
              [0, 0, 0, 1, 0, 1, 0, 0, 0, 0,],           
              [0, 0, 0, 0, 1, 0, 0, 0, 0, 0,],           
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])           

arr = "".join([str(x) for x in arr.reshape(-1)])         
print [len(x) for x in arr.replace("0"," ").split()] 

產量

[1, 7, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1] #Cluster sizes

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM