Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting the maximum in each rolling window of a 2D numpy array

I have a 2D numpy array and I want to get the maximum value contained in each 2d rolling window that starts from left to right, top to bottom, rolling one row or column each time. The most naive method would be iterating through all rolling windows and get the maximum of all values enclosed in this rolling window. I wrote down this method below:

import numpy as np
shape=(1050,300)
window_size=(120,60)
a = np.arange(shape[1]*shape[0]).reshape(shape[1],shape[0])
max_Map=np.full((shape[1]-window_size[1]+1,shape[0]-window_size[0]+1),0,dtype='uint32')

for i in range(shape[1]-window_size[1]+1):
    for j in range(shape[0]-window_size[0]+1):
        window_max=np.max(a[i:i+window_size[1],j:j+window_size[0]])
        max_Map[i][j]=window_max

But this is terribly inefficient, as there are only 2 rows(or 2 column) changed between each sliding but my code doesn't take into account any correlations between 2 consecutive rolling windows. An improvement I could think of is for each sliding window(assuming rolling horizontally) I will calculate the maximum of the left most column and the maximum of the remaining columns and take the max of the 2 values as the current window maximum. And for the next rolling window the maximum will be max of the newly added column and the previous remaining columns...But I still don't think this is optimized...

I will really appreciate it if someone can point me to the right direction,I feel like this should be a well studied problem but I couldn't find solutions anywhere... Thanks in advance!

like image 380
Susie Avatar asked May 14 '17 16:05

Susie


People also ask

What is the way to find the maximum number in the Numpy array?

Python Numpy – Get Maximum Value of Array Given a numpy array, you can find the maximum value of all the elements in the array. To get the maximum value of a Numpy Array, you can use numpy function numpy. max() function.

How do you find the index of the maximum value in a 2D array Python?

You can use argmax() to get the index of your maximum value.

What is Max in Numpy?

maximum() function is used to find the element-wise maximum of array elements. It compares two arrays and returns a new array containing the element-wise maxima. If one of the elements being compared is a NaN, then that element is returned.

What is Numpy 2D array?

2D array are also called as Matrices which can be represented as collection of rows and columns. In this article, we have explored 2D array in Numpy in Python. NumPy is a library in python adding support for large multidimensional arrays and matrices along with high level mathematical functions to operate these arrays.

How do I calculate the Rolling Max of a NumPy array?

This computes the "rolling max" of A (similar to rolling average) over a sliding window of length K: import numpy as np A = np.random.rand (100000) K = 10 rollingmax = np.array ( [max (A [j:j+K]) for j in range (len (A)-K)]) but I think it is far from optimal in terms of performance.

How to find the maximum and minimum of a NumPy array?

If we use 1 instead of 0, will get a list like [11 16 81], which contain the maximum number from each row. Example 4: If we have two same shaped NumPy arrays, we can find the maximum or minimum elements. For this step, we have to numpy.maximum (array1, array2) function.

What happens if we use 1 instead of 0 in NumPy?

If we use 1 instead of 0, will get a list like [11 16 81], which contain the maximum number from each row. Example 4: If we have two same shaped NumPy arrays, we can find the maximum or minimum elements.

How to create a single-dimensional array in NumPy?

Example 1: Now try to create a single-dimensional array. Here, we create a single-dimensional NumPy array of integers. Now try to find the maximum element. To do this we have to use numpy.max (“array name”) function. For finding the minimum element use numpy.min (“array name”) function.


1 Answers

Approach #1 Using Scipy's 2D max filter -

from scipy.ndimage.filters import maximum_filter as maxf2D

# Store shapes of inputs
N,M = window_size
P,Q = a.shape

# Use 2D max filter and slice out elements not affected by boundary conditions
maxs = maxf2D(a, size=(M,N))
max_Map_Out = maxs[M//2:(M//2)+P-M+1, N//2:(N//2)+Q-N+1]

Approach #2 Using Scikit's 2D sliding window views -

from skimage.util.shape import view_as_windows

N,M = window_size
max_Map_Out = view_as_windows(a, (M,N)).max(axis=(-2,-1))

Note on window size and its use : The original approach has the window sizes aligned in a flipped manner, i.e. the first shape parameter of window_size slides along the second axis, while the second shape parameter decides how the window slides along the first axis. This might not be the case for other problems that do sliding max filtering, where we usually use the first shape parameter for the first axis of the 2D array and similarly for the second shape parameter. So, to solve for those cases, simply use : M,N = window_size and use the rest of the codes as they are.

Runtime test

Approaches -

def org_app(a, window_size):
    shape = a.shape[1], a.shape[0]
    max_Map=np.full((shape[1]-window_size[1]+1,
                     shape[0]-window_size[0]+1),0,dtype=a.dtype)
    for i in range(shape[1]-window_size[1]+1):
        for j in range(shape[0]-window_size[0]+1):
            window_max=np.max(a[i:i+window_size[1],j:j+window_size[0]])
            max_Map[i][j]=window_max
    return max_Map

def maxf2D_app(a, window_size):
    N,M = window_size
    P,Q = a.shape
    maxs = maxf2D(a, size=(M,N))
    return maxs[M//2:(M//2)+P-M+1, N//2:(N//2)+Q-N+1]

def view_window_app(a, window_size):
    N,M = window_size
    return view_as_windows(a, (M,N)).max(axis=(-2,-1))

Timings and verification -

In [573]: # Setup inputs
     ...: shape=(1050,300)
     ...: window_size=(120,60)
     ...: a = np.arange(shape[1]*shape[0]).reshape(shape[1],shape[0])
     ...: 

In [574]: np.allclose(org_app(a, window_size), maxf2D_app(a, window_size))
Out[574]: True

In [575]: np.allclose(org_app(a, window_size), view_window_app(a, window_size))
Out[575]: True

In [576]: %timeit org_app(a, window_size)
1 loops, best of 3: 2.11 s per loop

In [577]: %timeit view_window_app(a, window_size)
1 loops, best of 3: 1.14 s per loop

In [578]: %timeit maxf2D_app(a, window_size)
100 loops, best of 3: 3.09 ms per loop

In [579]: 2110/3.09  # Speedup using Scipy's 2D max filter over original approach
Out[579]: 682.8478964401295
like image 158
Divakar Avatar answered Sep 21 '22 15:09

Divakar