Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Taking subarrays from numpy array with given stride/stepsize

Lets say I have a Python Numpy array a.

a = numpy.array([1,2,3,4,5,6,7,8,9,10,11]) 

I want to create a matrix of sub sequences from this array of length 5 with stride 3. The results matrix hence will look as follows:

numpy.array([[1,2,3,4,5],[4,5,6,7,8],[7,8,9,10,11]]) 

One possible way of implementing this would be using a for-loop.

result_matrix = np.zeros((3, 5)) for i in range(0, len(a), 3):   result_matrix[i] = a[i:i+5] 

Is there a cleaner way to implement this in Numpy?

like image 587
Stackd Avatar asked Oct 17 '16 11:10

Stackd


People also ask

What is stride in NumPy array?

The strides of an array tell us how many bytes we have to skip in memory to move to the next position along a certain axis. For example, we have to skip 4 bytes (1 value) to move to the next column, but 20 bytes (5 values) to get to the same position in the next row.

Is a Numpy Ndarray is faster than a built in list?

NumPy Arrays are faster than Python Lists because of the following reasons: An array is a collection of homogeneous data-types that are stored in contiguous memory locations. On the other hand, a list in Python is a collection of heterogeneous data types stored in non-contiguous memory locations.

Is Ndarray same as Numpy array?

numpy. array is just a convenience function to create an ndarray ; it is not a class itself. You can also create an array using numpy. ndarray , but it is not the recommended way.

Does Numpy support multidimensional arrays Ndarray?

Numpy is a library in Python adding support for large multidimensional arrays and matrices along with high level mathematical functions to operate these arrays.


2 Answers

Approach #1 : Using broadcasting -

def broadcasting_app(a, L, S ):  # Window len = L, Stride len/stepsize = S     nrows = ((a.size-L)//S)+1     return a[S*np.arange(nrows)[:,None] + np.arange(L)] 

Approach #2 : Using more efficient NumPy strides -

def strided_app(a, L, S ):  # Window len = L, Stride len/stepsize = S     nrows = ((a.size-L)//S)+1     n = a.strides[0]     return np.lib.stride_tricks.as_strided(a, shape=(nrows,L), strides=(S*n,n)) 

Sample run -

In [143]: a Out[143]: array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])  In [144]: broadcasting_app(a, L = 5, S = 3) Out[144]:  array([[ 1,  2,  3,  4,  5],        [ 4,  5,  6,  7,  8],        [ 7,  8,  9, 10, 11]])  In [145]: strided_app(a, L = 5, S = 3) Out[145]:  array([[ 1,  2,  3,  4,  5],        [ 4,  5,  6,  7,  8],        [ 7,  8,  9, 10, 11]]) 
like image 175
Divakar Avatar answered Sep 20 '22 05:09

Divakar


Starting in Numpy 1.20, we can make use of the new sliding_window_view to slide/roll over windows of elements.

And coupled with a stepping [::3], it simply becomes:

from numpy.lib.stride_tricks import sliding_window_view  # values = np.array([1,2,3,4,5,6,7,8,9,10,11]) sliding_window_view(values, window_shape = 5)[::3] # array([[ 1,  2,  3,  4,  5], #        [ 4,  5,  6,  7,  8], #        [ 7,  8,  9, 10, 11]]) 

where the intermediate result of the sliding is:

sliding_window_view(values, window_shape = 5) # array([[ 1,  2,  3,  4,  5], #        [ 2,  3,  4,  5,  6], #        [ 3,  4,  5,  6,  7], #        [ 4,  5,  6,  7,  8], #        [ 5,  6,  7,  8,  9], #        [ 6,  7,  8,  9, 10], #        [ 7,  8,  9, 10, 11]]) 
like image 20
Xavier Guihot Avatar answered Sep 18 '22 05:09

Xavier Guihot