2014-09-04 8 views
7

मेरे समस्या निम्नलिखित है,2 डी numpy सरणी में क्लस्टर आकार कैसे खोजें?

मैं उदाहरण के लिए 0 एक 1 से भरा एक 2 डी numpy सरणी, एक दिलचस्प सीमा शर्त (सभी बाहरी तत्वों 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]] 

मैं चाहता हूँ एक ऐसा फ़ंक्शन बनाने के लिए जो इस सरणी और उसके रैखिक आयाम एल को इनपुट पैरामीटर के रूप में लेता है, (इस मामले में एल = 10) और इस सरणी के क्लस्टर आकारों की सूची देता है।

द्वारा "समूहों" मैं सरणी

सरणी तत्व [मैं] [जे] अगर अपने सभी पड़ोसियों शून्य कर रहे हैं अलग है, और के तत्वों 1 की अलग समूहों मतलब अपने पड़ोसियों के तत्व हैं:

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

तो पिछले सरणी में हम आकार (2,1,2,6,1,1,1)

मैं दो कार्यों बनाने के द्वारा इस कार्य को पूरा करने की कोशिश की के 7 समूहों है, पहले एक है एक पुनरावर्ती समारोह:

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 के बराबर एक सरणी तत्व मिलता है, यह काउंटर "मान" के मान को बढ़ाता है और तत्व के मान को 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 

और यह क्लस्टर आकार युक्त सूची वापस आ जाएगी। 1 से एल -1 क्योंकि सभी बाहरी तत्वों 0.

यह काम नहीं करता और मैं नहीं देख सकते हैं, जहां त्रुटि है कर रहे हैं पाश दोहराता के लिए ...

मैं हो, तो हो सकता है सोच रहा था इसे करने का एक आसान तरीका।

उत्तर

7

यह एक रिसाव समस्या की तरह लगता है में कनवर्ट कर सकते हैं। यदि आपके पास 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 सदस्यों के साथ एक क्लस्टर के लिए होगा।

0

मेरा मानना ​​है कि आपका तरीका लगभग सही नहीं है, सिवाय इसके कि आप चरम count को बार-बार शुरू कर रहे हैं जब भी आप अपने फ़ंक्शन clust_size पर दोबारा कॉल करते हैं। मैं clust_size के इनपुट पैरामीटर में गिनती चर जोड़ दूंगा और count = 0 के साथ अपने नेस्टेड for लूप में प्रत्येक पहली कॉल के लिए इसे फिर से शुरू कर दूंगा।

इस तरह, आप clust_size को हमेशा count=clust_size(array, i ,j, count) पर कॉल करेंगे, मैंने इसका परीक्षण नहीं किया है, लेकिन ऐसा लगता है कि इसे काम करना चाहिए।

उम्मीद है कि यह मदद करता है।

-2

एक अपेक्षाकृत सरल समस्या आप तार

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 
1

मुझे "क्लस्टर" खोजने में आपकी समस्या महसूस होती है, यह अनिवार्य रूप से 4-कनेक्टिविटी के आधार पर बाइनरी छवि (या तो 0 या 1 के मानों के साथ) में जुड़े घटकों को खोजने की एक ही समस्या है। आप कई एल्गोरिदम इस विकिपीडिया पृष्ठ में जुड़ा घटकों (या "समूहों" के रूप में आप उन्हें परिभाषित) की पहचान करने के देख सकते हैं:

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

एक बार जुड़ा घटकों या "समूहों" नाम से पुकारा जाता है, तो आप किसी भी जानकारी प्राप्त कर सकते आप क्षेत्र, सापेक्ष स्थिति या किसी भी अन्य जानकारी सहित आसानी से चाहते हैं।

संबंधित मुद्दे