Можно ли объединить несмежные измерения в массиве NumPy без копирования данных? - PullRequest
1 голос
/ 13 января 2020

Я хотел бы объединить первое и последнее измерение массива 3-D NumPy в одно измерение, не копируя данные:

import numpy as np

data = np.empty((3, 4, 5))
data = data.transpose([0, 2, 1])

try:
  # this fails, indicating that it is not possible:
  # AttributeError: incompatible shape for a non-contiguous array
  data.shape = (-1, 4)
except AttributeError:
  # this creates a copy of the data:
  data = data.reshape((-1, 4))

Возможно ли это?

1 Ответ

3 голосов
/ 13 января 2020
In [55]: arr = np.arange(24).reshape(2,3,4)                                                               
In [56]: arr1 = arr.transpose(2,1,0)                                                                      
In [57]: arr                                                                                              
Out[57]: 
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 [58]: arr1                                                                                             
Out[58]: 
array([[[ 0, 12],
        [ 4, 16],
        [ 8, 20]],

       [[ 1, 13],
        [ 5, 17],
        [ 9, 21]],

       [[ 2, 14],
        [ 6, 18],
        [10, 22]],

       [[ 3, 15],
        [ 7, 19],
        [11, 23]]])

Посмотрите, как значения располагаются в буфере данных 1d:

In [59]: arr.ravel()                                                                                      
Out[59]: 
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 [60]: arr1.ravel()                                                                                     
Out[60]: 
array([ 0, 12,  4, 16,  8, 20,  1, 13,  5, 17,  9, 21,  2, 14,  6, 18, 10,
       22,  3, 15,  7, 19, 11, 23])

Если значения с округлением не У вас нет такого же порядка, вы не можете избежать копирования.

reshape имеет это примечание:

Вы можете думать о преобразовании как о первом расширении массива (используя заданного порядка индексов), затем вставляя элементы из массива raveled в новый массив, используя тот же тип порядка индексов, который использовался для raveling.

In [63]: arr1.reshape(-1,2)                                                                               
Out[63]: 
array([[ 0, 12],
       [ 4, 16],
       [ 8, 20],
       [ 1, 13],
       [ 5, 17],
       [ 9, 21],
       [ 2, 14],
       [ 6, 18],
       [10, 22],
       [ 3, 15],
       [ 7, 19],
       [11, 23]])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...