(209, 64, 64, 3)
выглядит как форма массива изображений, каждый из 209 изображений (64,64,3). Изменение формы должно сохранять эти элементы изображения вместе и в порядке.
Иллюстрируя на небольшом примере:
In [845]: arr = np.arange(24).reshape(4,2,3)
In [846]: arr
Out[846]:
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]]])
In [847]: arr[1]
Out[847]:
array([[ 6, 7, 8],
[ 9, 10, 11]])
Наивный вид:
In [848]: x = arr.reshape(6,4)
In [849]: x
Out[849]:
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]])
In [850]: x[:,1]
Out[850]: array([ 1, 5, 9, 13, 17, 21])
Выбор столбца приводит к другому набору чисел, чем в Out[847]
. [6,7,8]
теперь разделен между строками 2 и 3. И [1,5,9...]
взяты со всех концов arr
.
Изменение формы с последующим транспонированием: (4,2,3) => (4, (2 * 3)) => (4,6) => (6,4):
In [851]: x = arr.reshape(4,6).T
In [852]: x
Out[852]:
array([[ 0, 6, 12, 18],
[ 1, 7, 13, 19],
[ 2, 8, 14, 20],
[ 3, 9, 15, 21],
[ 4, 10, 16, 22],
[ 5, 11, 17, 23]])
In [853]: x[:,1]
Out[853]: array([ 6, 7, 8, 9, 10, 11])
In [855]: x[:,1].reshape(2,3)
Out[855]:
array([[ 6, 7, 8],
[ 9, 10, 11]])
Формально reshape
просто требует, чтобы общее количество элементов не менялось. Но, как показано здесь, подгруппы измерений также должны оставаться такими же, (4,2,3) => (4,6)
или (8,3)
, а не (6,4)
. В противном случае вы рискуете перегруппировать значения.
С помощью только изменения формы и транспонирования x
по-прежнему является view
, разделяя буфер данных с arr
. Но order
отличается. Дальнейшее изменение формы (например, ravel
) может привести к получению копии.
In [859]: arr.__array_interface__['data']
Out[859]: (36072624, False)
In [860]: x.__array_interface__['data']
Out[860]: (36072624, False)
In [861]: x.ravel()
Out[861]:
array([ 0, 6, 12, 18, 1, 7,...])
In [862]: x.ravel(order='F')
Out[862]:
array([ 0, 1, 2, 3, 4, 5, ...])