#python #numpy #numpy-ndarray #numpy-slicing
Вопрос:
У меня есть 3d-массив формы (3, 5, 5). Мне нужно срезать, используя разные индексы вдоль 2-й и 3-й осей для каждого из 3 элементов
ts = np.arange(25*3).reshape(3,5,5)
print(ts)
newr1 = np.array([1,0,2])
newr2 = np.array([3,2,4])
newc1 = np.array([1,2,0])
newc2 = np.array([3,4,2])
Я хочу что-то вроде ts[:, newr1:newr2, newc1:newc2]
, но этот тип нарезки работает только для скалярных индексов. Результат должен выглядеть так, как показано ниже. Пожалуйста, посоветуйте
array([[[ 6, 7, 8],
[11, 12, 13],
[16, 17, 18]],
[[27, 28, 29],
[32, 33, 34],
[37, 38, 39]],
[[60, 61, 62],
[65, 66, 67],
[70, 71, 72]]])
Комментарии:
1. Для индексирования не было бы векторизованного подхода, поскольку нет гарантии, что каждый подмассив будет возвращать данные с одинаковой формой.
2. Он должен был визуализировать выбор. Я думаю, вам нужно выразить это в виде итерации, объединения результатов или построения массивов индексирования. Это не
basic
индексация.
Ответ №1:
Ладно, мое любопытство взяло верх надо мной. Я найду ответ, даже если вы предоставили не так много информации, как следовало бы.
In [10]: ts = np.arange(25*3).reshape(3,5,5)
...: print(ts)
...: newr1 = np.array([1,0,2])
...: newr2 = np.array([3,2,4])
...:
...: newc1 = np.array([1,2,0])
...: newc2 = np.array([3,4,2])
...:
[[[ 0 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 49]]
[[50 51 52 53 54]
[55 56 57 58 59]
[60 61 62 63 64]
[65 66 67 68 69]
[70 71 72 73 74]]]
Я предполагаю, что то, чего ты хочешь, это:
In [11]: for i in range(3):
...: x = ts[i,newr1[i]:newr2[i],newc1[i]:newc2[i]]
...: print(x)
...:
[[ 6 7]
[11 12]]
[[27 28]
[32 33]]
[[60 61]
[65 66]]
Хорошо, это близко, хотя вы неправильно обработали конечные точки срезов.
linspace
способен генерировать «срезы/апельсины» для массивов входных данных:
In [13]: np.linspace(newr1,newr2,3)
Out[13]:
array([[1., 0., 2.],
[2., 1., 3.],
[3., 2., 4.]])
попытка использовать такие матрицы в качестве индекса приводит к ошибке:
In [14]: I=np.linspace(newr1,newr2,3)
In [15]: J=np.linspace(newc1,newc2,3)
In [16]: ts[np.arange(3)[:,None,None], I[:,:,None], J[:,None,:]]
Traceback (most recent call last):
File "<ipython-input-16-5bc9e51832b8>", line 1, in <module>
ts[np.arange(3)[:,None,None], I[:,:,None], J[:,None,:]]
IndexError: arrays used as indices must be of integer (or boolean) type
In [17]: I=np.linspace(newr1,newr2,3).astype(int)
In [18]: J=np.linspace(newc1,newc2,3).astype(int)
In [19]: I
Out[19]:
array([[1, 0, 2],
[2, 1, 3],
[3, 2, 4]])
In [20]: J
Out[20]:
array([[1, 2, 0],
[2, 3, 1],
[3, 4, 2]])
После пары ошибок я пришел к:
In [23]: ts[np.arange(3)[:,None,None], I.T[:,:,None], J.T[:,None,:]]
Out[23]:
array([[[ 6, 7, 8],
[11, 12, 13],
[16, 17, 18]],
[[27, 28, 29],
[32, 33, 34],
[37, 38, 39]],
[[60, 61, 62],
[65, 66, 67],
[70, 71, 72]]])
Поэтому, если размеры срезов совпадают по «плоскостям», мы можем сделать этот выбор с помощью соответствующего набора массивов индексов.