Измените массив в NumPy
Рассмотрим массив следующего вида (просто пример):
[[ 0 1]
[ 2 3]
[ 4 5]
[ 6 7]
[ 8 9]
[10 11]
[12 13]
[14 15]
[16 17]]
Это форма [9,2]. Теперь я хочу преобразовать массив так, чтобы каждый столбец стал формой [3,3], например:
[[ 0 6 12]
[ 2 8 14]
[ 4 10 16]]
[[ 1 7 13]
[ 3 9 15]
[ 5 11 17]]
Наиболее очевидным (и, безусловно, "непитоновым" ) решением является инициализация массива нулей с соответствующим размером и запуск двух циклов for-loop, где он будет заполнен данными. Я заинтересован в решении, которое соответствует языку...
Ответы
Ответ 1
a = np.arange(18).reshape(9,2)
b = a.reshape(3,3,2).swapaxes(0,2)
# a:
array([[ 0, 1],
[ 2, 3],
[ 4, 5],
[ 6, 7],
[ 8, 9],
[10, 11],
[12, 13],
[14, 15],
[16, 17]])
# b:
array([[[ 0, 6, 12],
[ 2, 8, 14],
[ 4, 10, 16]],
[[ 1, 7, 13],
[ 3, 9, 15],
[ 5, 11, 17]]])
Ответ 2
У numpy есть отличный инструмент для этой задачи ("numpy.reshape") ссылка на документацию по изменению формы
a = [[ 0 1]
[ 2 3]
[ 4 5]
[ 6 7]
[ 8 9]
[10 11]
[12 13]
[14 15]
[16 17]]
'numpy.reshape(a,(3,3))'
Вы также можете использовать трюк "-1"
'a = a.reshape(-1,3)'
"-1" - это подстановочный знак, который позволяет алгоритму "numpy" выбирать число, которое нужно ввести, когда второе измерение равно 3
так что да.. это также сработает: a = a.reshape(3,-1)
и это: a = a.reshape(-1,2)
ничего не сделает
и это: a = a.reshape(-1,9)
изменит форму на (2,9)
Ответ 3
Есть две возможные перестановки результатов (следующий пример @eumiro). Пакет Einops
предоставляет мощную нотацию для описания таких операций не однозначно
>> a = np.arange(18).reshape(9,2)
# this version corresponds to eumiro answer
>> einops.rearrange(a, '(x y) z -> z y x', x=3)
array([[[ 0, 6, 12],
[ 2, 8, 14],
[ 4, 10, 16]],
[[ 1, 7, 13],
[ 3, 9, 15],
[ 5, 11, 17]]])
# this has the same shape, but order of elements is different (note that each paer was trasnposed)
>> einops.rearrange(a, '(x y) z -> z x y', x=3)
array([[[ 0, 2, 4],
[ 6, 8, 10],
[12, 14, 16]],
[[ 1, 3, 5],
[ 7, 9, 11],
[13, 15, 17]]])