大于二维数组中某个值的最小相邻单元的索引

2024-03-29 07:01:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个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]])

我正在寻找单元格中最小的neighbours的索引,其中value= 2numpy.where(a==value))但大于value。我还需要相应单元格的索引=value,我们为其找到了最小的邻居。你知道吗

在这种情况下(value = 2)的结果应该是:

  • 邻近细胞指数:[0,2][4,3] 相应的和

  • 相应细胞的索引:[1,2][3,3]

如果问题不太清楚,请道歉。你知道吗

到目前为止,我的情况是:

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]))

这是非常缓慢的,也仍然不知道如何找到相应的细胞指数。任何与我的解决方案完全不同的解决方案也将被接受。你知道吗


Tags: numpyvaluenp情况neighbors指数minitem
3条回答

不确定这要快多少(如果有的话),但它找到了相应的单元格。你知道吗

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)]]

您可以使用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]])]

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)

它的作用是:

  • 在填充有vala上创建滑动窗口(因此窗口形状是(*a.shape, 3, 3)
  • 在中心有val的所有窗口中查找大于val的最小值(填充允许边的聚焦),并将其分配给min_val
  • neig_mask将相邻对象限制为基数方向
  • 查找min_val位于neig_mask位置且val位于中心的窗口,分配给rev_mask
  • 查找val位于neig_mask位置且min_val位于中心的窗口,分配给min_mask
  • 返回min_maskrev_mask中的np.nonzero,这些元组可以用作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)))
    

相关问题 更多 >