7

कहें कि मेरे पास निरंतर भिन्न कार्य के मूल्यांकन वाले न्यूमपी में एक सरणी है, और मैं स्थानीय मिनीमा ढूंढना चाहता हूं। कोई शोर नहीं है, इसलिए हर बिंदु जिसका मूल्य अपने पड़ोसियों के मूल्यों से कम है, स्थानीय न्यूनतम के लिए मेरे मानदंड को पूरा करता है।कुशलतापूर्वक NumPy में एक चिकनी multidimensional सरणी के स्थानीय minima कैसे खोजें?

import numpy as N 

def local_minima(array2d): 
    local_minima = [ index 
        for index in N.ndindex(array2d.shape) 
        if index[0] > 0 
        if index[1] > 0 
        if index[0] < array2d.shape[0] - 1 
        if index[1] < array2d.shape[1] - 1 
        if array2d[index] < array2d[index[0] - 1, index[1] - 1] 
        if array2d[index] < array2d[index[0] - 1, index[1]] 
        if array2d[index] < array2d[index[0] - 1, index[1] + 1] 
        if array2d[index] < array2d[index[0], index[1] - 1] 
        if array2d[index] < array2d[index[0], index[1] + 1] 
        if array2d[index] < array2d[index[0] + 1, index[1] - 1] 
        if array2d[index] < array2d[index[0] + 1, index[1]] 
        if array2d[index] < array2d[index[0] + 1, index[1] + 1] 
        ] 
    return local_minima 

बहरहाल, यह काफी धीमी है:

मैं निम्न सूची समझ जो एक दो आयामी सरणी के लिए काम करता है, सीमाओं पर संभावित न्यूनतम अनदेखी की है। मैं इसे किसी भी आयाम के लिए काम करने के लिए भी प्राप्त करना चाहता हूं। उदाहरण के लिए, क्या किसी भी आयाम की किसी सरणी में किसी बिंदु के सभी पड़ोसियों को प्राप्त करने का कोई आसान तरीका है? या क्या मैं इस समस्या को गलत तरीके से पूरा कर रहा हूं? क्या मुझे इसके बजाय numpy.gradient() का उपयोग करना चाहिए?

+0

वैश्विक अधिकतमता ढूँढना: http://stackoverflow.com/questions/3584243/python-get-the-position-of-the-biggest-item-in-an-numpy-array/3584260#3584260 – endolith

उत्तर

14

स्थानीय न्यूनतम के स्थान का उपयोग कर मनमाना आयाम की एक सरणी Ivan के detect_peaks function के लिए पाया जा सकता है, मामूली संशोधनों के साथ:

import numpy as np 
import scipy.ndimage.filters as filters 
import scipy.ndimage.morphology as morphology 

def detect_local_minima(arr): 
    # https://stackoverflow.com/questions/3684484/peak-detection-in-a-2d-array/3689710#3689710 
    """ 
    Takes an array and detects the troughs using the local maximum filter. 
    Returns a boolean mask of the troughs (i.e. 1 when 
    the pixel's value is the neighborhood maximum, 0 otherwise) 
    """ 
    # define an connected neighborhood 
    # http://www.scipy.org/doc/api_docs/SciPy.ndimage.morphology.html#generate_binary_structure 
    neighborhood = morphology.generate_binary_structure(len(arr.shape),2) 
    # apply the local minimum filter; all locations of minimum value 
    # in their neighborhood are set to 1 
    # http://www.scipy.org/doc/api_docs/SciPy.ndimage.filters.html#minimum_filter 
    local_min = (filters.minimum_filter(arr, footprint=neighborhood)==arr) 
    # local_min is a mask that contains the peaks we are 
    # looking for, but also the background. 
    # In order to isolate the peaks we must remove the background from the mask. 
    # 
    # we create the mask of the background 
    background = (arr==0) 
    # 
    # a little technicality: we must erode the background in order to 
    # successfully subtract it from local_min, otherwise a line will 
    # appear along the background border (artifact of the local minimum filter) 
    # http://www.scipy.org/doc/api_docs/SciPy.ndimage.morphology.html#binary_erosion 
    eroded_background = morphology.binary_erosion(
     background, structure=neighborhood, border_value=1) 
    # 
    # we obtain the final mask, containing only peaks, 
    # by removing the background from the local_min mask 
    detected_minima = local_min - eroded_background 
    return np.where(detected_minima)  

जो आप इस तरह उपयोग कर सकते हैं:

arr=np.array([[[0,0,0,-1],[0,0,0,0],[0,0,0,0],[0,0,0,0],[-1,0,0,0]], 
       [[0,0,0,0],[0,-1,0,0],[0,0,0,0],[0,0,0,-1],[0,0,0,0]]]) 
local_minima_locations = detect_local_minima(arr) 
print(arr) 
# [[[ 0 0 0 -1] 
# [ 0 0 0 0] 
# [ 0 0 0 0] 
# [ 0 0 0 0] 
# [-1 0 0 0]] 

# [[ 0 0 0 0] 
# [ 0 -1 0 0] 
# [ 0 0 0 0] 
# [ 0 0 0 -1] 
# [ 0 0 0 0]]] 

यह कहता है कि न्यूनतम सूचकांक [0,0,3], [0,4,0], [1,1,1] और [1,3,3]:

print(local_minima_locations) 
# (array([0, 0, 1, 1]), array([0, 4, 1, 3]), array([3, 0, 1, 3])) 
print(arr[local_minima_locations]) 
# [-1 -1 -1 -1] 
+0

अच्छा! यह मेरे मूल के रूप में लगभग 65 गुना तेजी से चलता है, और किसी भी आयाम के लिए काम करता है। – ptomato

3

2 डी के लिए इस प्रयास करें:

import numpy as N 

def local_minima(array2d): 
    return ((array2d <= N.roll(array2d, 1, 0)) & 
      (array2d <= N.roll(array2d, -1, 0)) & 
      (array2d <= N.roll(array2d, 1, 1)) & 
      (array2d <= N.roll(array2d, -1, 1))) 

यह आपको सही/गलत जहां स्थानीय न्यूनतम (चार पड़ोसियों) स्थित हैं के साथ एक array2d जैसी सरणी वापस आ जाएगी।

+0

ठीक है, यह वास्तव में स्थानीय अधिकतमता पाता है, और '&& 'के बजाय' '' 'की आवश्यकता होती है, और तुलना के आसपास कोष्ठक की आवश्यकता होती है, लेकिन यह मेरे मूल की तुलना में तीस गुना तेजी से चलती है। – ptomato

+0

@ptomato - आप सही हैं, अभी सही, धन्यवाद। – eumiro

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