0

I have 3 4x4 arrays (matrices) created with: arr=np.linspace(1,48,48).reshape(3,4,4)

The matrices appear as below: `

[[[ 1.  2.  3.  4.]
  [ 5.  6.  7.  8.]
  [ 9. 10. 11. 12.]
  [13. 14. 15. 16.]]

 [[17. 18. 19. 20.]
  [21. 22. 23. 24.]
  [25. 26. 27. 28.]
  [29. 30. 31. 32.]]

 [[33. 34. 35. 36.]
  [37. 38. 39. 40.]
  [41. 42. 43. 44.]
  [45. 46. 47. 48.]]]`

I would like to perform indexing/splicing to obtain certain outputs eg:

[[36. 35.] [40. 39.] [44. 43.] [48. 47.]]

[[13. 9. 5. 1.] [29. 25. 21. 17.] [45. 41. 37. 33.]]


[[25. 26. 27. 28.], [29. 30. 31. 32.], [33. 34. 35. 36.], [37. 38. 39. 40.]]

4*. [[1. 4.] [45. 48.]]

I am struggling with exactly how to approach it. When working with a particular matrix, I have attempted to access that matrix and then splice/index from there. For example, the output [[36. 35.] [40. 39.] [44. 43.] [48. 47.]] lies in the third matrix. I access the matrix like this matrix3 = arr[array([2])]

Now I am only working with rows and columns in the third matrix and am finding it difficult to slice correctly. Should matrix3[::-1,::-1] invert both columns and rows? If yes then is this the best way to approach it? Instead, should I use reshape and should you use reshape on all 3 4x4 arrays or access the matrix you want to work with and then reshape?

edit: added 4.

2 Answers 2

2

Extracting your first result, step by step:

In [53]: arr[2,:,:]            # the desired plane
Out[53]: 
array([[33, 34, 35, 36],
       [37, 38, 39, 40],
       [41, 42, 43, 44],
       [45, 46, 47, 48]])
In [54]: arr[2,:,2:]          # the desired columns
Out[54]: 
array([[35, 36],
       [39, 40],
       [43, 44],
       [47, 48]])
In [55]: arr[2,:,:1:-1]        # the reversed order
Out[55]: 
array([[36, 35],
       [40, 39],
       [44, 43],
       [48, 47]])

or if it's easier, reverse as a separate step:

In [56]: arr[2,:,2:][:,::-1]
Out[56]: 
array([[36, 35],
       [40, 39],
       [44, 43],
       [48, 47]])

2nd

In [57]: arr[:,:,0]          # select column
Out[57]: 
array([[ 1,  5,  9, 13],
       [17, 21, 25, 29],
       [33, 37, 41, 45]])
In [58]: arr[:,::-1,0]        # reverse
Out[58]: 
array([[13,  9,  5,  1],
       [29, 25, 21, 17],
       [45, 41, 37, 33]])
In [59]: arr[:,::-1,0].T      # transpose
Out[59]: 
array([[13, 29, 45],
       [ 9, 25, 41],
       [ 5, 21, 37],
       [ 1, 17, 33]])

3rd

This is a little trickier. We want last 2 rows for one plane, and first two for another plane. To get that we need a pair on indices that will broadcast to the correct shape, pairing up 1 with [2,3] etc.

In [61]: arr[[[1],[2]],[[2,3],[0,1]],:]
Out[61]: 
array([[[25, 26, 27, 28],
        [29, 30, 31, 32]],

       [[33, 34, 35, 36],
        [37, 38, 39, 40]]])

This is a 3d matrix; one way to reduce it to 2d is to concatenate:

In [63]: np.concatenate(arr[[[1],[2]],[[2,3],[0,1]],:],axis=0)
Out[63]: 
array([[25, 26, 27, 28],
       [29, 30, 31, 32],
       [33, 34, 35, 36],
       [37, 38, 39, 40]])

reshape works just as well:

In [65]: arr[[[1],[2]],[[2,3],[0,1]],:].reshape(4,4)
Out[65]: 
array([[25, 26, 27, 28],
       [29, 30, 31, 32],
       [33, 34, 35, 36],
       [37, 38, 39, 40]])

Also arr.reshape(3,2,2,4)[[1,2],[1,0],:].reshape(4,4)


You can write these indexing expressions as tuples with slices, e.g.:

In [66]: idx = (2, slice(None), slice(None,1,-1))
In [67]: arr[idx]
Out[67]: 
array([[36, 35],
       [40, 39],
       [44, 43],
       [48, 47]])

So in general the common tools include indexing (with slices, scalars and lists), reversing (-1 step), transposing (or swapaxes), and reshaping. You can't do everything with just one of these.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you. Breaking down the slicing into steps really helped with clarifying which positions affect the matrix.
0

You're on the right track with the slicing! For your desired outputs try:

arr[2,:,:1:-1]
np.vstack((arr[i, ::-1, 0] for i in range(3)))
np.vstack((arr[1, 2:, :], arr[2, :2, :]))

Output:

array([[36., 35.],
   [40., 39.],
   [44., 43.],
   [48., 47.]])

array([[13.,  9.,  5.,  1.],
   [29., 25., 21., 17.],
   [45., 41., 37., 33.]])

array([[25., 26., 27., 28.],
   [29., 30., 31., 32.],
   [33., 34., 35., 36.],
   [37., 38., 39., 40.]])

Comments

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.