Ответ 1
Что насчет
c = np.stack((a,b), axis=3)
У меня есть два массива 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]
соответствовали исходным двум массивам.
Что насчет
c = np.stack((a,b), axis=3)
Здесь вы идете:
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)
Как насчет следующего:
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)
Принятый ответ выше отлично. Но я добавлю следующее, потому что я математический 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
Это работает для меня:
c = numpy.array([a,b])
Хотя было бы неплохо, если бы это тоже сработало.
Это не обязательно самый элегантный, но я использовал варианты
c = rollaxis(array([a,b]), 0, 4)
в прошлом.