2

So lets say I have a an array that looks similar to this :

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

I would like to return the location of the center of the largest sum of values within a certain n*n square. So in this case it would be (2,2) if n = 3. If I let n = 4 it would be the same result.

Does numpy have a method for finding this location?

1
  • if n was 4, wouldn't there be 2 problems: there is no centre index and in your example, all convolutions would have the same sum... No? Commented Oct 28, 2017 at 19:17

1 Answer 1

2

Approach #1 : We can use SciPy's 2D convolution to get summations in sliding windows of shape (n,n) and choose the index of the window with the biggest sum with argmax and translate to row, col indices with np.unravel_index, like so -

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)

Sample run -

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)

Approach #1S (Super charged) : We can boost it further by using uniform filter, like so -

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)

Approach #2 : Another based on scikit-image's sliding window creating tool view_as_windows, we would create sliding windows of shape (n,n) to give us a 4D array with the last two axes of shape (n,n) corresponding to the search window size. So, we would sum along those two axes and get the argmax index and translate it to the actual row, col positions.

Hence, the implementation would be -

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)

As also mentioned in the comments, a search square with an even n would be confusing given that it won't have its center at any element coordinate.

Runtime test

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
Sign up to request clarification or add additional context in comments.

6 Comments

Sweet! Thank you, it works for what I needed it to work for however, is there another method that I can apply using slicing and loops and potentially dictionaries?
@ASK Should be straight-forward with loops. Give that a try. Not really good with dictionaries.
okay I tried it a few different ways but I don't seem to be able to store or sum up the values. the other problem I have is I don't know how to create an array of a certain n*n size that will iterate over the given array that I'm trying to find the location of the data in. can you chime in?
@ASK Maybe ask a new question specifically saying you need to use dictionaries/loops only. Though that would defeat the purpose of using NumPy, which is performance. Why do you need to use loops/dictionaries, when vectorized methods as suggested would be faster?
Because I'm curious to see how it works, since that is the method I tried doing originally.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.