Давайте рассмотрим основы массива - он имеет плоский буфер данных, shape
, strides
и dtype
.Эти три атрибута используются для view
элементов буфера данных особым образом, будь то простая 1d последовательность, 2d или более высокие измерения.
Истина view
, чем использование того же буфера данных, но применяет к нему другую форму, шаг или dtype.
Чтобы получить [2, 4, 3, 1]
из [1,2,3,4]
, необходимо начать с 2
, прыгнуть вперед 2, затем перейти назад к 1 и вперед 2. Это нерегулярный шаблон, который может быть представлен как strides
.
arr[1::2]
дает [2,4], а arr[0::2]
дает [1,3]
.
(U, V, S, T)
до (U*S, V*T)
требуется транспонирование в (U, S, V, T)
с последующим изменением формы
arr.transpose(0,2,1,3).reshape(U*S, V*T)
Для этого потребуется копия, никак не обойтись.
In [227]: arr = np.arange(2*3*4*5).reshape(2,3,4,5)
In [230]: arr1 = arr.transpose(0,2,1,3).reshape(2*4, 3*5)
In [231]: arr1.shape
Out[231]: (8, 15)
In [232]: arr1
Out[232]:
array([[ 0, 1, 2, 3, 4, 20, 21, 22, 23, 24, 40, 41, 42,
43, 44],
[ 5, 6, 7, 8, 9, 25, 26, 27, 28, 29, 45, 46, 47,
48, 49],
....)
Или с вашим x
In [234]: x1 = x.transpose(0,2,1,3).reshape(4,4)
In [235]: x1
Out[235]:
array([[1, 1, 2, 2],
[1, 1, 2, 2],
[3, 3, 4, 4],
[3, 3, 4, 4]])
Обратите внимание, что элементы расположены в другом порядке:
In [254]: x.ravel()
Out[254]: array([1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4])
In [255]: x1.ravel()
Out[255]: array([1, 1, 2, 2, 1, 1, 2, 2, 3, 3, 4, 4, 3, 3, 4, 4])
ndarray.sort
на месте и меняет порядок байтов в буфере данных.Он работает на низком уровне, к которому у нас нет доступа.Это не view
исходного массива.