简体   繁体   English

最小相邻像元的索引大于2D数组中的值

[英]Index of smallest neighbouring cell greater than a value in 2D array

I have a numpy array a: 我有一个numpy数组

a = np.array([[0,4,3,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10],
          [4,4,3,5,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10],
          [4,8,3,9,2,6,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10],
          [4,2,2,9,2,6,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10],
          [4,4,2,9,2,6,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10],
          [4,2,2,2,2,8,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10],
          [4,2,2,2,6,8,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10],
          [4,2,2,2,6,8,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10],
          [4,2,2,2,6,8,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10],
          [4,2,2,2,6,8,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10],
          [4,2,2,2,6,8,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10],
          [4,2,2,9,2,6,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10],
          [4,2,2,2,6,8,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10],
          [4,4,2,2,6,8,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10],
          [4,4,4,3,4,4,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10],
          [4,4,4,3,4,4,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10]])

I'm looking for the index of the smallest neighbours of cell(s) where value= 2 ( numpy.where(a==value) ) but bigger than value . 我正在寻找value= 2numpy.where(a==value) )但大于value的单元格最小邻居的索引。 I also need the index of the corresponding cell(s) = value for which we found the smallest neighbour. 我还需要找到最小邻居的相应单元格的索引= value

Result in this case ( value = 2 ) should be: 在这种情况下,结果( value = 2 )应为:

  • index of neighbouring cells: [0,2] and [4,3] The corresponding and 相邻单元的索引: [0,2][4,3]

  • index of corresponding cell(s): [1,2] and [3,3] 相应单元格的索引: [1,2][3,3]

Please apologies if the question is not very clear. 如果问题不太清楚,请您道歉。

This is what I have so far: 这是我到目前为止的内容:

import numpy as np
value = 2
neighbors = np.zeros(4, dtype = np.float)
fdx = np.flatnonzero(a== value)
locations = fdx // a.shape[1], fdx % a.shape[1]
maximums = []
for item in zip(*locations):
    i, j = item[0], item[1]
    neighbors[0], neighbors[1], neighbors[2],neighbors[3] = [a[i-1,j], a[i+1,j], a[i,j-1], a[i,j+1]]
    maximums.append(min(neighbors[neighbors> value]))
print np.where(a==min(maximums))

prints: (array([0, 4]), array([2, 3]))

Which is very slow and also still don't know how to find the index of corresponding cells. 这是非常慢的,并且仍然不知道如何找到相应单元格的索引。 Any solution which is totally different to my solution would be also accepted. 任何与我的解决方案完全不同的解决方案也将被接受。

You can find neighbors using scipy.ndimage.morphology.binary_dilation 您可以使用scipy.ndimage.morphology.binary_dilation找到邻居

import numpy as np
from scipy.ndimage import morphology
a = np.array([[0,4,3,9,9,9],
              [4,4,2,2,2,9],
              [4,2,2,9,2,6],
              [4,2,2,2,6,8],
              [4,4,4,3,4,4]])
k = 2

# make mask
eq = a==k
# find greater neighbors (as mask)
nbs = morphology.binary_dilation(eq) & (a>k)
# translate to index
minidx = np.argwhere(nbs & (a == np.min(a[nbs])))

# now find neighbors' neighbors
# pad original mask
m,n = a.shape
eqp = np.zeros((m+2, n+2), bool)
eqp[1:-1,1:-1] = eq
# generate offset vectors for the four major directions (up, down, left, right)
# corrected for padding
offsp = np.array([(0,1),(2,1),(1,0),(1,2)])
# without padding correction
offs = offsp - 1#
# for each minimum, find all (1-4) reference neighbors
refidx = [i + offs[eqp[tuple((i+offsp).T)]] for i in minidx]

print(minidx)
print(refidx)

# [[0 2]
#  [4 3]]
# [array([[1, 2]]), array([[3, 3]])]

Not sure how much faster (if at all) this is, but it finds the corresponding cells. 不知道这有多快(如果有的话),但是它会找到相应的单元。

import numpy as np

a = np.array([[0,4,3,9,9,9],
          [4,4,2,2,2,9],
          [4,2,2,9,2,6],
          [4,2,2,2,6,8],
          [4,4,4,3,4,4]])

value = 2
idx = np.where(a == value)
idx = zip(idx[0],idx[1])

running_min = np.inf
corresponding_idx = []#corresponding cells
nb_min_list = []#location of neighbors
nb_min_idx = []
for i in idx:
    nb_idx = [(i[0]+1,i[1]),(i[0]-1,i[1]),(i[0],i[1]+1),(i[0],i[1]-1)]#note no check for out of bounds.
    nb_idx = [nb for nb in nb_idx if nb[0] >= 0 and nb[0] < a.shape[0] and nb[1] >= 0 and nb[1] < a.shape[1]]#test for edges

    try:
        nb_min = min([a[nb] for nb in nb_idx if a[nb] > value])
        corresponding_idx.append(i)
        nb_min_list.append(nb_min)
        nb_min_idx.append([nb for nb in nb_idx if a[nb] == nb_min])
    except:
        pass

nb_min_loc = np.where(nb_min_list == min(nb_min_list))[0]
corresponding_cells = []
min_nbs = []
for nb in nb_min_loc:
    corresponding_cells.append(corresponding_idx[nb])
    min_nbs.append(nb_min_idx[nb])

print(corresponding_cells)#[(1, 2), (3, 3)]
print(min_nbs)#[[(0, 2)], [(4, 3)]]

Using window_nd from a previous answer 使用上一个答案中的 window_nd

def min_search(a, val = 2):
        a_view = window_nd(np.pad(a, ((1, 1),(1, 1)), 'constant',
                           constant_values = np.inf), 3)
        min_val = np.where(a_view[a == val] <= val, np.inf, a_view[a == val]).min()
        neig_mask = np.array([[0, 1, 0], [1, 0, 1], [0, 1, 0]], dtype = bool)
        rev_mask = np.logical_and(np.any(np.logical_and(a_view == min_val,
                                         neig_mask), axis = (-1, -2)), a == val)
        min_mask = np.logical_and(np.any(np.logical_and(a_view == val,
                                         neig_mask), axis = (-1, -2)), a == min_val)

        return np.nonzero(min_mask), np.nonzero(rev_mask)

What this does: 这是做什么的:

  • Creates a sliding window over a padded with val (so the windowed shape is (*a.shape, 3, 3) ) 创建在滑动窗口a带衬垫val (因此加窗的形状是(*a.shape, 3, 3)
  • finds the minimum value greater than val among all windows with val at the center (padding allows inlcusion of edges) an assigns it to min_val 在所有以val为中心的窗口中找到大于val的最小值(填充允许边缘的插入),并将其分配给min_val
  • neig_mask restricts neigbors to cardinal directions neig_mask将neigbors限制在基本方向上
  • finds windows with min_val in neig_mask positions and val in the center, assigns to rev_mask 查找在neig_mask位置具有min_val且在中央具有val窗口,分配给rev_mask
  • finds windows with val in neig_mask positions and min_val in the center, assigns to min_mask 发现窗户valneig_mask位置和min_val在中央,分配给min_mask
  • returns np.nonzero of min_mask and rev_mask , which are tuples that can be used as an index on a 返回np.nonzeromin_maskrev_mask ,它们是可被用作一个索引元组a

     min_search(a) Out: ((array([0, 4], dtype=int32), array([2, 3], dtype=int32)), (array([1, 3], dtype=int32), array([2, 3], dtype=int32))) 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM