Selecting multiple slices from a numpy array at once Selecting multiple slices from a numpy array at once numpy numpy

Selecting multiple slices from a numpy array at once


stride_tricks can do that

a = np.arange(10)b = np.lib.stride_tricks.as_strided(a, (3, 5), 2 * a.strides)b# array([[0, 1, 2, 3, 4],#        [1, 2, 3, 4, 5],#        [2, 3, 4, 5, 6]])

Please note that b references the same memory as a, in fact multiple times (for example b[0, 1] and b[1, 0] are the same memory address). It is therefore safest to make a copy before working with the new structure.

nd can be done in a similar fashion, for example 2d -> 4d

a = np.arange(16).reshape(4, 4)b = np.lib.stride_tricks.as_strided(a, (3,3,2,2), 2*a.strides)b.reshape(9,2,2) # this forces a copy# array([[[ 0,  1],#         [ 4,  5]],#        [[ 1,  2],#         [ 5,  6]],#        [[ 2,  3],#         [ 6,  7]],#        [[ 4,  5],#         [ 8,  9]],#        [[ 5,  6],#         [ 9, 10]],#        [[ 6,  7],#         [10, 11]],#        [[ 8,  9],#         [12, 13]],#        [[ 9, 10],#         [13, 14]],#        [[10, 11],#         [14, 15]]])


You can use the indexes to select the rows you want into the appropriate shape.For example:

 data = np.random.normal(size=(100,2,2,2)) # Creating an array of row-indexes indexes = np.array([np.arange(0,5), np.arange(1,6), np.arange(2,7)]) # data[indexes] will return an element of shape (3,5,2,2,2). Converting # to list happens along axis 0 data_extractions = list(data[indexes]) np.all(data_extractions[1] == data[1:6]) True

The final comparison is against the original data.


In this post is an approach with strided-indexing scheme using np.lib.stride_tricks.as_strided that basically creates a view into the input array and as such is pretty efficient for creation and being a view occupies nomore memory space.Also, this works for ndarrays with generic number of dimensions.

Here's the implementation -

def strided_axis0(a, L):    # Store the shape and strides info    shp = a.shape    s  = a.strides    # Compute length of output array along the first axis    nd0 = shp[0]-L+1    # Setup shape and strides for use with np.lib.stride_tricks.as_strided    # and get (n+1) dim output array    shp_in = (nd0,L)+shp[1:]    strd_in = (s[0],) + s    return np.lib.stride_tricks.as_strided(a, shape=shp_in, strides=strd_in)

Sample run for a 4D array case -

In [44]: a = np.random.randint(11,99,(10,4,2,3)) # ArrayIn [45]: L = 5      # Window length along the first axisIn [46]: out = strided_axis0(a, L)In [47]: np.allclose(a[0:L], out[0])  # Verify outputsOut[47]: TrueIn [48]: np.allclose(a[1:L+1], out[1])Out[48]: TrueIn [49]: np.allclose(a[2:L+2], out[2])Out[49]: True