2016-10-31 8 views
5

मैं एक numpy सरणी में 1 के लगातार स्पैन का पता लगाने के लिए चाहता हूँ। दरअसल, मैं पहले यह पहचानना चाहता हूं कि सरणी में तत्व कम से कम तीन 1 की अवधि में है या नहीं। उदाहरण के लिए, हमारे पास निम्न सरणी है:numpy: एक सरणी में लगातार 1 का पता लगाएं

import numpy as np 
    a = np.array([1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0]) 

फिर निम्न 1 में बोल्ड में तत्व तत्वों को पूरा करते हैं।

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

इसके बाद, 1 की के दो फैला द्वारा अधिक से अधिक दो 0 के अलग होती है, तो दो फैला ऊपर एक लंबे समय तक काल बनाते हैं। तो ऊपर सरणी

रूप charaterized है [1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0]

दूसरे शब्दों में, इनपुट के रूप में मूल सरणी के लिए, मैं उत्पादन चाहते हैं इस प्रकार है:

[True, True, True, True, True, True, True, False, False, False, False, False, True, True, True, True, True, True, True, True, True, True, False] 

मैं के बारे में सोच कर दिया गया है इस फ़ंक्शन को लागू करने के लिए एक एल्गोरिदम, लेकिन मैं जिस के साथ आता हूं वह जटिल लगता है ईडी। तो मुझे इसे लागू करने के बेहतर तरीके जानना अच्छा लगेगा - अगर कोई मेरी मदद कर सकता है तो इसकी बहुत सराहना की जाएगी।

अद्यतन:

मैं माफी माँगता हूँ कि मैं अपने प्रश्न स्पष्ट नहीं किया। मैं 1 की अवधि के रूप में सरणी में 3 या अधिक लगातार 1 की पहचान करना चाहता हूं, और 1 के किसी भी दो स्पैन के बीच केवल एक या दो 0 के बीच पहचान की जाती है, अलग-अलग 0 के साथ, एक लंबी अवधि के रूप में। मेरा लक्ष्य निम्न तरीके से समझा जा सकता है: यदि 1 के स्पैन के बीच केवल एक या दो 0 हैं, तो मैं उन 0 को त्रुटियों के रूप में मानता हूं और उन्हें 1 के रूप में सही किया जाना चाहिए।

@ ritesht93 ने एक उत्तर दिया जो लगभग मुझे जो चाहिए वह देता है। हालांकि, वर्तमान उत्तर उस मामले की पहचान नहीं करता है जब 1 के तीन स्पैन होते हैं जो 0 के द्वारा अलग होते हैं, जिन्हें एक एकल अवधि के रूप में पहचाना जाना चाहिए। उदाहरण के लिए, सरणी

a2 = np.array([0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0]) 

के लिए हम उत्पादन प्राप्त करना चाहिए

[False, True, True, True, True, True, True, True, True, 
    True, True, True, True, True, False, False, False, False, 
    False, True, True, True, True, True, False] 

अद्यतन 2:

मैं बहुत से प्रेरित था और नियमित अभिव्यक्ति के आधार पर एल्गोरिथ्म पाया करने के लिए सबसे आसान है कार्यान्वित करें और समझने के लिए - हालांकि मैं अन्य विधियों की तुलना में कुशल के बारे में निश्चित नहीं हूं। आखिरकार मैंने निम्नलिखित विधि का इस्तेमाल किया।

lst = np.array([0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0]) 
    lst1 = re.sub(r'1{3,}', lambda x:'c'*len(x.group()), ''.join(map(str, lst))) 
    print lst1 

जो 1 के

0ccc0ccc00cccc00100ccccc0 

का फैला पहचान और उसके बाद का फैला कनेक्ट 1 के

lst2 = re.sub(r'c{1}0{1,2}c{1}', lambda x:'c'*len(x.group()), ''.join(map(str, lst1))) 
    print lst2 

जो देता है

0ccccccccccccc00100ccccc0 

अंतिम परिणाम

0 द्वारा दिया जाता है
np.array(list(lst2)) == 'c' 

    array([False, True, True, True, True, True, True, True, True, 
    True, True, True, True, True, False, False, False, False, 
    False, True, True, True, True, True, False]) 
+0

"सरणी विशेषता के रूप में:" और "उत्पादन चाहते हैं इस प्रकार है" एक दूसरे के विपरीत है: पदों 8 और 9 एक "काल" का हिस्सा होना चाहिए ("सही") या नहीं (बोल्ड नहीं) ? – hvwaldow

+0

@hvwaldow हाँ, आप सही हैं। यह बात बताने के लिए धन्यवाद। एरियल ने सही किया। – user3821012

+0

"हालांकि, वर्तमान उत्तर उस मामले की पहचान नहीं करता है जब 1 के तीन स्पैन होते हैं जो 0 के द्वारा अलग होते हैं ...." हम्म। मुझे यह नहीं दिख रहा है। मेरा जवाब आपके दूसरे टेस्टकेस के लिए सही समाधान का उत्पादन प्रतीत होता है। – hvwaldow

उत्तर

1
इसके बजाय पाशन के परंपरागत तरीके से सुलझाने और गिनती हम एक ही स्ट्रिंग के लिए सभी 0 और 1 के बदलने और एक और चार के साथ एक regex मैच की जगह ले सकता बनाए रखने की

2 का कहना है। एक बार ऐसा करने के बाद हम स्ट्रिंग को फिर से विभाजित करते हैं और प्रत्येक char पर bool() की जांच करते हैं।

>>> import re 
>>> lst=[1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0] 
>>> list(map(bool, map(int, list(re.sub(r'1{3,}0{1,2}1{3,}', lambda x:'2'*len(x.group()), ''.join(map(str, lst))))))) 
[True, True, True, True, True, True, True, False, True, True, False, False, True, True, True, True, True, True, True, True, True, True, False] 
>>> 

सभी आपरेशनों यहाँ पर होती हैं:

re.sub(r'1{3,}0{1,2}1{3,}', lambda x:'2'*len(x.group()), ''.join(map(str, lst))) 

जहां यह 3 या उससे अधिक 1 के एक सन्निहित घटना पर सबसे 2 0 के यानी 1 या 2 0 के द्वारा पीछा द्वारा 3 या उससे अधिक 1 के पीछे हो लिए खोज करता है और पूरे मिलान वाली स्ट्रिंग को 2 की समान लंबाई स्ट्रिंग के साथ प्रतिस्थापित करता है (प्रयुक्त 2 क्योंकि bool(2)True है)। np.array([1,2, 3, 4, 5, 6]).tolist()

संपादित करें 1: इसके अलावा, आप इस तरह NumPy सरणी के बाहर एक सूची प्राप्त करने NumPy में tolist() विधि का उपयोग कर सकते हैं

>>> lst=[1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0] 
>>> import re 
>>> list(map(lambda x:False if x == 0 or x ==1 else True, map(int, list(re.sub(r'1{3,}0{1,2}1{3,}', lambda x:'2'*len(x.group()), ''.join(map(str, lst))))))) 
[True, True, True, True, True, True, True, False, False, False, False, False, True, True, True, True, True, True, True, True, True, True, False] 
>>> 

संपादित करें: प्रश्न में एक परिवर्तन के बाद, यहाँ अद्यतन जवाब है 2 अंतिम जवाब:

>>> import re 
>>> lst=[0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0] 
>>> while re.subn(r'[12]{3,}0{1,2}[12]{3,}', lambda x:'2'*len(x.group()), ''.join(map(str, lst)))[1]: 
...  lst=re.subn(r'[12]{3,}0{1,2}[12]{3,}', lambda x:'2'*len(x.group()), ''.join(map(str, lst)))[0] 
... 
>>> lst 
'0222222222222200100111110' 
>>> lst=list(re.sub(r'1{3,}', lambda x:'2'*len(x.group()), ''.join(map(str, lst)))) 
>>> lst 
['0', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '0', '0', '1', '0', '0', '2', '2', '2', '2', '2', '0'] 
>>> list(map(lambda x:False if x == 0 or x ==1 else True, map(int, lst))) 
[False, True, True, True, True, True, True, True, True, True, True, True, True, True, False, False, False, False, False, True, True, True, True, True, False] 
>>> 
+0

यह मूल प्रश्न में सुधार के बाद वांछित परिणाम नहीं देता है। यद्यपि ठीक करने के लिए आसान होना चाहिए। – hvwaldow

+0

अच्छा, नहीं, ऐसा नहीं है। प्रत्येक बार आपके पास '0,1,1,0,1,1,1,0,1,1,0' जैसे कुछ' 1' पकड़े नहीं जाएंगे। – hvwaldow

+0

@hvwaldow क्षमा करें .. ऑफलाइन था, बस अपडेट किए गए प्रश्न को देखा और – ritesht93

2

हम binary dilation औरके संयोजन के साथ इसे हल कर सकता हैपहले चरण पिछले पाने के लिए और उसके बाद binary closing तो की तरह, अंतिम आउटपुट प्राप्त करने के लिए -

from scipy.ndimage.morphology import binary_erosion,binary_dilation,binary_closing 

K = np.ones(3,dtype=int) # Kernel 
b = binary_dilation(binary_erosion(a,K),K) 
out = binary_closing(b,K) | b 

नमूना चलाता

प्रकरण # 1:

In [454]: a 
Out[454]: array([1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0]) 

In [456]: out 
Out[456]: 
array([ True, True, True, True, True, True, True, False, False, 
     False, False, False, True, True, True, True, True, True, 
     True, True, True, True, False], dtype=bool) 

प्रकरण # 2:

In [460]: a 
Out[460]: 
array([0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0]) 

In [461]: out 
Out[461]: 
array([False, True, True, True, True, True, True, True, True, 
     True, True, True, True, True, False, False, False, False, 
     False, True, True, True, True, True, False], dtype=bool) 
1

मुझे पता है कि यह इतना नहीं है "पायथो n-वार ", लेकिन आप कलन विधि के बारे में वार्ता के बाद से, मैं इसे एक कोशिश देने का फैसला किया

import numpy as np 
a = np.array([1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0]) 
b = np.array([int]) 

#init 2nd array 
for x in range (0,(a.size-1)): 
    b = np.append(b,0) 

print (b) 
#1st case 
for x in range (2,(a.size)): 
    if (a[x-2]==1 & a[x-1]==1 & a[x]==1): #1-1-1 
     b[x] = 1 
     b[x-1] = 1 
     b[x-2] = 1 

print (b) 
#2nd case 
for x in range (2,(b.size)): 
    if (b[x-2]==1 & b[x]==1): #1-0-1 
     if (b[x-1]==0): #sorry, i forget about logical op. in python 
      b[x-1] = 1 

print (b) 
#3rd case 
for x in range (3,(b.size)): 
    if (b[x-3]==1 & b[x]==1): #1-0-0-1 
     if (b[x-2]==0 & b[x]-1==0): 
      b[x-1] = 1 
      b[x-2] = 1 

#4th case 
for x in range (4,(b.size)): 
    if (a[x-4]==1 & a[x-3]==1 & b[x]): #1-1-0-0-1 
     if (a[x-2]==0 & a[x]-1==0): 
      b[x-3] = 1 
      b[x-4] = 1 
print (b) 

मैं अगर यह वास्तव में अपने अपेक्षित परिणाम है यकीन नहीं है (माफ करना, मैं अजगर के साथ इतना परिचित नहीं हूँ), लेकिन यहाँ यह है:
[1 1 1 1 1 1 1 0 1 1 0 0 1 1 1 1 1 1 1 1 1 1 0]

1

यह करने के लिए कई तरीके।मैं इसे समूह में विभाजित कर दूंगा, समूहों और समूहों को संचालन के लिए प्लीज स्थितियों में विभाजित करता है। इसलिए जैसा:

from itertools import groupby, starmap 
import numpy as np 

a = np.array([1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0]) 

def condition(groups, key, newkey, minlen): 
    return [(newkey, l) if l < minlen and k == key else (k, l) for k, l in groups] 

def flatten(groups): 
    return [k for g in starmap(lambda k, l: l * [k], groups) for k in g] 

def group(l): 
    return [(k, len(list(v))) for k, v in groupby(l)] 

res = group(flatten(condition(group(a), 1, 0, 3))) 
# groups zeros at the beginning or the end never change to ones, 
# no matter their length 
res = flatten([res[0]] + condition(res[1:-1], 0, 1, 3) + [res[-1]]) 
print [bool(v) for v in res] 
संबंधित मुद्दे