【问题标题】:Find location of the largest sum in 2d numpy array在二维 numpy 数组中查找最大和的位置
【发布时间】:2018-04-10 03:18:14
【问题描述】:

所以假设我有一个看起来与此类似的数组:

array([[0, 0, 0, 0, 0],
       [0, 1, 1, 1, 0],
       [0, 1, 1, 1, 0],
       [0, 1, 1, 1, 0],
       [0, 0, 0, 0, 0]])

我想返回某个 n*n 方格内最大值总和的中心位置。所以在这种情况下,如果 n = 3,它将是 (2,2)。如果我让 n = 4,结果将是相同的。

numpy 有找到这个位置的方法吗?

【问题讨论】:

  • 如果n4,不会有2 问题:没有中心index 并且在您的example 中,所有卷积都将具有相同的sum ...没有?

标签: python arrays numpy area


【解决方案1】:

方法#1:我们可以使用SciPy's 2D convolution在形状为(n,n)的滑动窗口中求和,并选择与argmax和最大的窗口的索引并转换为行, col 索引为np.unravel_index,就像这样 -

from scipy.signal import convolve2d as conv2

def largest_sum_pos_app1(a, n):
    idx = conv2(a, np.ones((n,n),dtype=int),'same').argmax()
    return np.unravel_index(idx, a.shape)

示例运行 -

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

In [559]: largest_sum_pos_app1(a, n=3)
Out[559]: (2, 2)

方法 #1S(超级充电):我们可以使用 uniform filter 进一步提升它,就像这样 -

from scipy.ndimage.filters import uniform_filter as unif2D

def largest_sum_pos_app1_mod1(a, n):
    idx = unif2D(a.astype(float),size=n, mode='constant').argmax()
    return np.unravel_index(idx, a.shape)

方法#2:另一个基于scikit-image的滑动窗口创建工具view_as_windows,我们将创建形状为(n,n)的滑动窗口给我们一个4D数组最后两个形状轴(n,n) 对应于搜索窗口大小。因此,我们将沿这两个轴求和并获得 argmax 索引并将其转换为实际的行 col 位置。

因此,实现将是 -

from skimage.util.shape import view_as_windows

def largest_sum_pos_app2(a, n):
    h = (n-1)//2 # half window size
    idx = view_as_windows(a, (n,n)).sum((-2,-1)).argmax()
    return tuple(np.array(np.unravel_index(idx, np.array(a.shape)-n+1))+h)

正如 cmets 中也提到的,带有偶数 n 的搜索方块会令人困惑,因为它的中心不会在任何元素坐标处。

运行时测试

In [741]: np.random.seed(0)

In [742]: a = np.random.randint(0,1000,(1000,1000))

In [743]: largest_sum_pos_app1(a, n= 5)
Out[743]: (966, 403)

In [744]: largest_sum_pos_app1_mod1(a, n= 5)
Out[744]: (966, 403)

In [745]: largest_sum_pos_app2(a, n= 5)
Out[745]: (966, 403)

In [746]: %timeit largest_sum_pos_app1(a, n= 5)
     ...: %timeit largest_sum_pos_app1_mod1(a, n= 5)
     ...: %timeit largest_sum_pos_app2(a, n= 5)
     ...: 
10 loops, best of 3: 57.6 ms per loop
100 loops, best of 3: 10.1 ms per loop
10 loops, best of 3: 47.7 ms per loop

【讨论】:

  • 甜蜜!谢谢,它适用于我需要它的工作但是,我可以使用切片和循环以及潜在的字典来应用另一种方法吗?
  • @ASK 应该是直截了当的循环。试试看。字典不太好。
  • 好的,我尝试了几种不同的方法,但我似乎无法存储或总结这些值。我遇到的另一个问题是我不知道如何创建一个特定 n*n 大小的数组,该数组将遍历给定数组,我试图在其中找到数据的位置。你能插话吗?
  • @ASK 也许问一个新问题,专门说你只需要使用字典/循环。尽管这会破坏使用 NumPy 的目的,即性能。当建议的矢量化方法更快时,为什么需要使用循环/字典?
  • 因为我很好奇它是如何工作的,因为那是我最初尝试做的方法。
猜你喜欢
  • 2015-05-09
  • 2017-04-03
  • 1970-01-01
  • 2019-03-31
  • 1970-01-01
  • 2021-06-27
  • 1970-01-01
  • 2017-02-13
  • 2014-02-27
相关资源
最近更新 更多