Оптимизированный Numpy изменяет форму: 2D-массив в 3D - PullRequest
0 голосов
/ 16 февраля 2019

Мне было интересно, есть ли более питонный / эффективный способ преобразования моего 2d-массива в 3d-массив?Вот следующий рабочий код:

import numpy as np
#
# Declaring the dimensions
n_ddl = 2
N = 3
n_H = n_ddl*N
#
# Typical 2D array to reshape
x_tilde_2d = np.array([[111,112,121,122,131,132],[211,212,221,222,231,232],[311,312,321,322,331,332]])
x_tilde_2d = x_tilde_2d.T
#
# Initialization of the output 3D array
x_tilde_reshaped_3d = np.zeros((N,x_tilde_2d.shape[1],n_ddl))
for i in range(0,x_tilde_2d.shape[1],1):
    x_tilde_sol = x_tilde_2d[:,i]
    x_tilde_sol_reshape = x_tilde_sol.reshape((N,n_ddl))
    for j in range(0,n_ddl,1):
        x_tilde_reshaped_3d[:,i,j] = x_tilde_sol_reshape[:,j]

Вот необработанный ожидаемый результат:

array([[[111., 112.],
        [211., 212.],
        [311., 312.]],

       [[121., 122.],
        [221., 222.],
        [321., 322.]],

       [[131., 132.],
        [231., 232.],
        [331., 332.]]])

и тот же результат по оси = 2:

x_tilde_reshaped_3d[:,:,0] = np.array([[111., 211., 311.],
                                       [121., 221., 321.],
                                       [131., 231., 331.]])

x_tilde_reshaped_3d[:,:,1] = np.array([[112., 212., 312.],
                                       [122., 222., 322.],
                                       [132., 232., 332.]])

Любые предложения будут ценны.Благодаря.

Ответы [ 2 ]

0 голосов
/ 16 февраля 2019
In [337]: x=np.array([[111,112,121,122,131,132],[211,212,221,222,231,232],[311,3
     ...: 12,321,322,331,332]])
In [338]: x.shape
Out[338]: (3, 6)
In [339]: x
Out[339]: 
array([[111, 112, 121, 122, 131, 132],
       [211, 212, 221, 222, 231, 232],
       [311, 312, 321, 322, 331, 332]])

Единственное изменение формы, при котором последнее измерение сохраняется в правильном порядке:

In [340]: x.reshape(3,3,2)
Out[340]: 
array([[[111, 112],
        [121, 122],
        [131, 132]],

       [[211, 212],
        [221, 222],
        [231, 232]],

       [[311, 312],
        [321, 322],
        [331, 332]]])

Теперь просто поменяйте местами первые два измерения:

In [341]: x.reshape(3,3,2).transpose(1,0,2)
Out[341]: 
array([[[111, 112],
        [211, 212],
        [311, 312]],

       [[121, 122],
        [221, 222],
        [321, 322]],

       [[131, 132],
        [231, 232],
        [331, 332]]])
0 голосов
/ 16 февраля 2019

Почему бы просто не сделать reshape напрямую.Кажется, нет необходимости сначала инициализировать трехмерную матрицу нулей, а затем заполнять их по размерам.

Желаемый порядок может быть достигнут путем замены первой и второй осей с помощью swapaxes(0, 1)

EDITED Ответ

x_tilde_2d = np.array([[111,112,121,122,131,132],[211,212,221,222,231,232],[311,312,321,322,331,332]])
x_tilde_reshaped_3d  = x_tilde_2d.reshape(N, x_tilde_2d.T.shape[1], n_ddl).swapaxes(0, 1)
print (x_tilde_reshaped_3d)

Выход

[[[111 112]
  [211 212]
  [311 312]]

 [[121 122]
  [221 222]
  [321 322]]

 [[131 132]
  [231 232]
  [331 332]]]
...