0

I'm given such 2D-array.

enter image description here

My task is to find max values in subarrays painted by different colours. I have to use strides and as_strided. So far my code looked like this:

a=np.vstack(([0,1,2,3,4,5],[6,7,8,9,10,11],[12,13,14,15,16,17],[18,19,20,21,22,23]))
print(np.max(np.lib.stride_tricks.as_strided(a,(2,3),strides=(24,4))))

It properly shows the maximum value of the first block, which is 8, but i have no idea how can i move to the other parts of the matrix.Is there any way i could move to the other parts of the matrix so i could show the max value of the subarray?

NOTE: This task is from my introduction classes to python programming, so there is no need to write any sophisticated functions, i would even say it is inadvisable

martineau
  • 119,623
  • 25
  • 170
  • 301
Matthias
  • 59
  • 1
  • 5
  • If you want a (2,2) array of `max`, I think you want a stridded array with shape (2,2,2,3) – hpaulj Mar 08 '20 at 00:49
  • Hint: look at `a.reshape(2,2,2,3).strides`. The right stride values are, just not in the right order. – hpaulj Mar 08 '20 at 01:05

2 Answers2

1
In [297]: a = np.arange(24).reshape(4,6)                                                       
In [298]: a                                                                                    
Out[298]: 
array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11],
       [12, 13, 14, 15, 16, 17],
       [18, 19, 20, 21, 22, 23]])

If we reshape size 4 dim to (2,2), and the 6 to (2,3):

In [299]: a.reshape(2,2,2,3)                                                                   
Out[299]: 
array([[[[ 0,  1,  2],
         [ 3,  4,  5]],

        [[ 6,  7,  8],
         [ 9, 10, 11]]],


       [[[12, 13, 14],
         [15, 16, 17]],

        [[18, 19, 20],
         [21, 22, 23]]]])

The order of the blocks isn't right, but we can correct that with a transpose:

In [300]: a.reshape(2,2,2,3).transpose(0,2,1,3)                                                
Out[300]: 
array([[[[ 0,  1,  2],
         [ 6,  7,  8]],

        [[ 3,  4,  5],
         [ 9, 10, 11]]],


       [[[12, 13, 14],
         [18, 19, 20]],

        [[15, 16, 17],
         [21, 22, 23]]]])

and the get the max of each of the 2d inner blocks:

In [301]: a.reshape(2,2,2,3).transpose(0,2,1,3).max((2,3))                                     
Out[301]: 
array([[ 8, 11],
       [20, 23]])

a.reshape(2,2,2,3).max((1,3)) gets the same max.

OK, that wasn't done with strides, but it gives me ideas of how to use strides.

strides of a itself:

In [303]: a.strides                                                                            
Out[303]: (48, 8)

after reshape:

In [304]: a.reshape(2,2,2,3).strides                                                           
Out[304]: (96, 48, 24, 8)

and after transpose:

In [305]: a.reshape(2,2,2,3).transpose(0,2,1,3).strides                                        
Out[305]: (96, 24, 48, 8)

So we can use those strides directly:

In [313]: np.lib.stride_tricks.as_strided(a,(2,2,2,3),(96,24,48,8))                            
Out[313]: 
array([[[[ 0,  1,  2],
         [ 6,  7,  8]],

        [[ 3,  4,  5],
         [ 9, 10, 11]]],


       [[[12, 13, 14],
         [18, 19, 20]],

        [[15, 16, 17],
         [21, 22, 23]]]])
hpaulj
  • 221,503
  • 14
  • 230
  • 353
0
import numpy as np

from numpy.lib.stride_tricks import as_strided

matrix = np.arange(24).reshape(4, 6)

maxtrix = np.array([as_strided(matrix[0], (2, 3), matrix.strides).max(),
                    as_strided(matrix[0][3:6], (2, 3), matrix.strides).max(),
                    as_strided(matrix[2], (2, 3), matrix.strides).max(),
                    as_strided(matrix[2][3:6], (2, 3), matrix.strides).max()
                    ]).reshape(2, 2)