Объединение двух массивов numpy в 4-ом измерении

У меня есть два массива numpy с тремя размерами (3 x 4 x 5), и я хочу объединить их, чтобы результат имел четыре измерения (3 x 4 x 5 x 2). В Matlab это можно сделать с помощью cat(4, a, b), но не в Numpy.

Например:

a = ones((3,4,5))
b = ones((3,4,5))
c = concatenate((a,b), axis=3) # error!

Чтобы уточнить, я хочу, чтобы c[:,:,:,0] и c[:,:,:,1] соответствовали исходным двум массивам.

Ответ 1

Что насчет

c = np.stack((a,b), axis=3)

Ответ 2

Здесь вы идете:

import numpy as np
a = np.ones((3,4,5))
b = np.ones((3,4,5))
c = np.concatenate((a[...,np.newaxis],b[...,np.newaxis]),axis=3)

Ответ 3

Как насчет следующего:

c = concatenate((a[:,:,:,None],b[:,:,:,None]), axis=3)

Это дает массив (3 x 4 x 5 x 2), который, как я полагаю, выложен так, как вам нужно.

Здесь None является синонимом np.newaxis: Numpy: следует ли использовать newaxis или None?

edit Как пояснил @Joe Kington, код можно немного очистить, используя многоточие:

c = concatenate((a[...,None],b[...,None]), axis=3)

Ответ 4

Принятый ответ выше отлично. Но я добавлю следующее, потому что я математический dork, и это приятно использовать тот факт, что a.shape есть a.T.shape[::-1]... i.e. перенос транспонирования меняет порядок индексов массива numpy. Поэтому, если у вас есть ваши строительные блоки в массиве, называемом блоками, то вышеописанное решение:

new = np.concatenate([block[..., np.newaxis] for block in blocks],
                     axis=len(blocks[0].shape))

но вы также можете сделать

new2 = np.array([block.T for block in blocks]).T

который, как я думаю, читается более чисто. Стоит отметить, что уже принятый ответ выполняется быстрее:

%%timeit
new = np.concatenate([block[..., np.newaxis] for block in blocks],
                     axis=len(blocks[0].shape))
1000 loops, best of 3: 321 µs per loop

а

%%timeit
new2 = np.array([block.T for block in blocks]).T
1000 loops, best of 3: 407 µs per loop

Ответ 5

Это работает для меня:

 c = numpy.array([a,b])

Хотя было бы неплохо, если бы это тоже сработало.

Ответ 6

Это не обязательно самый элегантный, но я использовал варианты

c = rollaxis(array([a,b]), 0, 4)

в прошлом.