Преобразование массива с множеством измерений в двумерный массив с помощью вложенных массивов - PullRequest
0 голосов
/ 29 мая 2018

Я хотел бы преобразовать массив со многими измерениями (более 2) в двумерный массив, где другие измерения были бы преобразованы во вложенные автономные массивы.

Так что, если у меня есть массив, такой как numpy.arange(3 * 4 * 5 * 5 * 5).reshape((3, 4, 5, 5, 5)), Я хотел бы преобразовать его в массив формы (3, 4), где каждый элемент был бы массивом формы (5, 5, 5).Dtype внешнего массива будет object.

Например, для np.arange(8).reshape((1, 1, 2, 2, 2)) вывод будет эквивалентен:

a = np.ndarray(shape=(1,1), dtype=object)
a[0, 0] = np.arange(8).reshape((1, 1, 2, 2, 2))[0, 0, :, :, :]

Как я могу сделать это эффективно?

Ответы [ 2 ]

0 голосов
/ 29 мая 2018

Мы можем изменить форму и назначить элементы из массива normal в массив dtype выходного объекта в одном цикле, который кажется немного быстрее, чем с двумя циклами, например -

def reshape_approach(a):
    m,n = a.shape[:2]
    a.shape = (m*n,) + a.shape[2:]
    out = np.empty((m*n),dtype=object)
    for i in range(m*n):
        out[i] = a[i]
    out.shape = (m,n)
    a.shape = (m,n) + a.shape[1:]
    return out

Испытание во время выполнения

Другой подход (-ы) -

# @Scotty1-'s soln
def simply_assign(a):
    m,n = a.shape[:2]
    out = np.empty((m,n),dtype=object)
    for i in range(m):
        for j in range(n):
            out[i,j] = a[i,j]
    return out

Время -

In [154]: m,n = 300,400
     ...: a = np.arange(m * n * 5 * 5 * 5).reshape((m,n, 5, 5, 5))

In [155]: %timeit simply_assign(a)
10 loops, best of 3: 39.4 ms per loop

In [156]: %timeit reshape_approach(a)
10 loops, best of 3: 32.9 ms per loop

С 7D данные -

In [160]: m,n,p,q = 30,40,30,40
     ...: a = np.arange(m * n *p * q * 5 * 5 * 5).reshape((m,n,p,q, 5, 5, 5))

In [161]: %timeit simply_assign(a)
1000 loops, best of 3: 421 µs per loop

In [162]: %timeit reshape_approach(a)
1000 loops, best of 3: 316 µs per loop
0 голосов
/ 29 мая 2018

Спасибо за подсказку, Митар.Вот как это должно выглядеть при использовании dtype=np.object массивов:

outer_array = np.empty((x.shape[0], x.shape[1]), dtype=np.object)
for i in range(x.shape[0]):
    for j in range(x.shape[1]):
        outer_array[i, j] = x[i, j]

Цикл может быть не самым эффективным способом сделать это, но для этой задачи нет векторизованной операции..

(При некотором изменении формы это должно быть даже быстрее, чем решение Divakar:;)) ---> Нет, Divakar быстрее .... Отличное решение Divakar!

def advanced_reshape_solution(x):
    m, n = x.shape[:2]
    sub_arr_size = np.prod(x.shape[2:])
    out_array = np.empty((m * n), dtype=object)
    x_flat_view = x.reshape(-1)
    for i in range(m*n):
        out_array[i] = x_flat_view[i * sub_arr_size:(i + 1) * sub_arr_size].reshape(x.shape[2:])
    return out_array.reshape((m, n))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...