Нарезка / индексирование с многомерными массивами с использованием Numpy - PullRequest
0 голосов
/ 29 мая 2018

У меня есть 3 массива 4x4 (матрицы), созданных с помощью: arr=np.linspace(1,48,48).reshape(3,4,4)

Матрицы отображаются следующим образом: `

[[[ 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.]]]`

Я хотел бы выполнить индексирование / сплайсинг для получения определенныхнапример:

[[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.]]

Я бьюсь над тем, как именно к нему подойти.При работе с определенной матрицей я пытался получить доступ к этой матрице, а затем соединить / индексировать оттуда.Например, вывод [[36.35.] [40.39.] [44.43.] [48.47.]] лежит в третьей матрице.Я получаю доступ к матрице следующим образом: matrix3 = arr[array([2])]

Теперь я работаю только со строками и столбцами в третьей матрице и затрудняюсь правильно их нарезать.Должен ли matrix3[::-1,::-1] инвертировать столбцы и строки?Если да, то лучший ли это подход?Вместо этого я должен использовать reshape, и вы должны использовать reshape для всех массивов 3x4x или получить доступ к матрице, с которой вы хотите работать, а затем изменить форму?

edit: добавлено 4.

Ответы [ 2 ]

0 голосов
/ 29 мая 2018

Извлечение вашего первого результата, шаг за шагом:

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]])

или, если это проще, в обратном порядке как отдельный шаг:

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

2-й

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

Это немного сложнее.Мы хотим, чтобы последние 2 строки были для одной плоскости, а первые две - для другой.Чтобы получить это, нам нужна пара по индексам, которая будет транслироваться в правильной форме: пара 1 с [2,3] и т. Д.

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]]])

Это трехмерная матрица;один из способов уменьшить его до 2d - объединить:

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]])

изменение формы работает так же хорошо:

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]])

Также arr.reshape(3,2,2,4)[[1,2],[1,0],:].reshape(4,4)


Вы можетезапишите эти выражения индексации в виде кортежей со слайсами, например:

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]])

Таким образом, в общем, общие инструменты включают индексирование (со слайсами, скалярами и списками), реверсирование (-1 шаг), транспонирование (или свопаксы),и изменение формы.Вы не можете сделать все с помощью одного из них.

0 голосов
/ 29 мая 2018

Вы на правильном пути с нарезкой!Для желаемых выходов попробуйте:

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

Выход:

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.]])
...