2017-10-28 123 views
0

所以可以說我有一個數組,看起來與此類似:查找2D numpy的陣列最大總和的位置

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有沒有找到這個位置的方法?

+0

如果'N'是'4',就不會有'2'問題:沒有中心'index'並在'example',所有卷積會有相同的'總和'...不是嗎? –

回答

0

方法1:我們可以使用SciPy's 2D convolution獲得求和滑動形狀(n,n)的窗戶和argmax選擇具有最大總和窗口的指數和轉化爲行,列指數以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索引並將其轉換爲實際的行,列的位置。

因此,實現起來 -

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) 

也如在評論中提到,有一個甚至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 
+0

甜!謝謝,它適用於我需要的工作,但是,還有另一種方法可以使用切片和循環以及可能的字典應用嗎? – ASK

+0

@ASK應該直接帶循環。試試看。字典不太好。 – Divakar

+0

好吧我嘗試了幾種不同的方式,但我似乎無法存儲或總結值。我遇到的另一個問題是我不知道如何創建一個具有n * n大小的數組,這個數組將迭代給定的數組,我試圖找到數據的位置。 – ASK