Транспонирование одномерного массива NumPy

Я использую Python и NumPy, и у меня проблемы с "транспонированием":

import numpy as np
a = np.array([5,4])
print(a)
print(a.T)

Вызов a.T не транспонирует массив. Если a - это, например, [[],[]], то он переставляется правильно, но мне нужно транспонирование [...,...,...].


person thaking    schedule 10.05.2011    source источник
comment
также пробовал напечатать a.transpose, который такой же, но без успеха, а не транспонировать ...   -  person thaking    schedule 10.05.2011
comment
Я пришел к выводу, что Python не является математическим, как Matlab, поэтому этот результат выглядит странно (у меня есть фон Matlab, и мне это тоже показалось странным)   -  person Humberto Fioravante Ferro    schedule 17.07.2021


Ответы (16)


Он работает именно так, как должен. Транспонирование массива 1D по-прежнему остается массивом 1D! (Если вы привыкли к Matlab, в нем принципиально нет концепции одномерного массива. «1D» массивы Matlab являются двухмерными.)

Если вы хотите превратить свой одномерный вектор в двухмерный массив, а затем транспонировать его, просто нарежьте его с помощью np.newaxis (или None, они такие же, newaxis просто более читабельны).

import numpy as np
a = np.array([5,4])[np.newaxis]
print(a)
print(a.T)

В общем, вам не стоит об этом беспокоиться. Добавление дополнительного измерения обычно не то, что вы хотите, если вы делаете это просто по привычке. Numpy будет автоматически транслировать 1D-массив при выполнении различных вычислений. Обычно нет необходимости различать вектор-строку и вектор-столбец (ни один из которых не является векторами. Они оба 2D!), Когда вам просто нужен вектор.

person Joe Kington    schedule 10.05.2011
comment
@thaking - Я просто использовал np.arange, чтобы быстро создать одномерный массив. Это работает точно так же для a = np.array([5,4]). - person Joe Kington; 10.05.2011
comment
@thaking Если вы новичок в numpy - имейте в виду, что круглые скобки () не указывают на дополнительное измерение в numpy. Если a = np.arange(10), то a - это array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), созданный a.__repr__(). Это одномерный (т.е. a.ndim --> 1) вектор, обозначенный квадратными скобками []. array( ... ) не отображается, когда вы делаете print(a) или a.__str__(). - person dtlussier; 11.05.2012
comment
@JoeKington есть ситуация, когда полезно транслировать одномерный массив. Вычисление расстояния между всеми одномерными точками в массиве. Благодаря вашему решению можно сделать x - x [np.newaxis] .T, который дает матрицу расстояний - person JuanPi; 25.04.2013
comment
Лично я считаю np.vstack() операцию более явной: print np.vstack(a). - person Alexander Pozdneev; 21.09.2016
comment
MATLAB имеет концепцию одномерного массива / вектора - person Vass; 20.10.2016
comment
Это не просто Matlab, но линейная алгебра имеет концепцию вектора строки / столбца. Numpy уникален для людей, пришедших из разных мест, а не только из Matlab. - person eric; 29.12.2018

Используйте две пары скобок вместо одной. Это создает двумерный массив, который можно транспонировать, в отличие от одномерного массива, который вы создаете, если используете одну пару скобок.

import numpy as np    
a = np.array([[5, 4]])
a.T

Более подробный пример:

>>> a = [3,6,9]
>>> b = np.array(a)
>>> b.T
array([3, 6, 9])         #Here it didn't transpose because 'a' is 1 dimensional
>>> b = np.array([a])
>>> b.T
array([[3],              #Here it did transpose because a is 2 dimensional
       [6],
       [9]])

Используйте метод numpy shape, чтобы узнать, что здесь происходит:

>>> b = np.array([10,20,30])
>>> b.shape
(3,)
>>> b = np.array([[10,20,30]])
>>> b.shape
(1, 3)
person savagent    schedule 11.05.2012
comment
Я предпочитаю это решение [np.newaxis], оно выглядит более элегантно. - person PhilMacKay; 20.03.2014
comment
Машины не такие уж умные. Даже если у вас только одна жена, ее следует объявить вашей первой женой. - person Sreeragh A R; 31.01.2020
comment
Это должен быть выбранный ответ - person bruno; 30.03.2020
comment
@bruno, Джо Кингтон точно ответил на вопрос. Ответ Савагента резок и полезен, но он объяснил кое-что еще. - person Humberto Fioravante Ferro; 17.07.2021

Для одномерных массивов:

a = np.array([1, 2, 3, 4])
a = a.reshape((-1, 1)) # <--- THIS IS IT

print a
array([[1],
       [2],
       [3],
       [4]])

Как только вы поймете, что -1 здесь означает «столько строк, сколько необходимо», я считаю, что это наиболее читаемый способ «транспонирования» массива. Если ваш массив имеет более высокую размерность, просто используйте a.T.

person Ulf Aslak    schedule 04.04.2016
comment
Обратите внимание, что это работает только с векторами. Если у вас есть двумерный массив, операции transpose и reshape изменяют массив по-разному (форма результирующего изображения такая же, но элементы размещаются по-разному). - person johndodo; 21.02.2017
comment
Спасибо за ваше замечание. Я понимаю вашу точку зрения, но думаю, что это больше отвлекает, чем проясняет мой ответ, потому что я даю простое однострочное решение точного вопроса, который фреймы @thaking. Речь идет не о 2-мерных массивах, а о 1-мерных массивах. Здесь яблоки и груши. - person Ulf Aslak; 21.02.2017
comment
Конечно. Ваш ответ правильный и элегантный для этого случая, я никогда не хотел его критиковать. Но, учитывая заголовок вопроса (Транспонирование массива NumPy), я подозреваю, что многие посетители придут сюда в поисках более общего решения, и я хотел предупредить их, что это не применимо к 2D-массивам. В противном случае ваш ответ правильный и подходит для вопроса ОП. - person johndodo; 07.03.2017
comment
@UlfAslak, пожалуйста, обновите свой ответ, что ваш подход не может быть обобщен на массив ND, всегда хорошо заранее прояснить, как предлагает! Johndodo, чтобы никто не использовал вашу технику неправильно.!, Вопрос здесь для правильного ответа и не лайнер.! - person Anu; 11.12.2018

Вы можете преобразовать существующий вектор в матрицу, заключив его в дополнительные квадратные скобки ...

from numpy import *
v=array([5,4]) ## create a numpy vector
array([v]).T ## transpose a vector into a matrix

numpy также имеет класс matrix (см. массив против матрицы) ...

matrix(v).T ## transpose a vector into a matrix
person Brent Bradburn    schedule 13.02.2013
comment
матричный класс скоро устареет, верно? - person Humberto Fioravante Ferro; 18.07.2021

numpy 1D массив → матрица столбцов / строк:

>>> a=np.array([1,2,4])
>>> a[:, None]    # col
array([[1],
       [2],
       [4]])
>>> a[None, :]    # row, or faster `a[None]`
array([[1, 2, 4]])

И, как сказал @ joe-kington, вы можете заменить None на np.newaxis для удобства чтения.

person ankostis    schedule 26.11.2014

Чтобы «транспонировать» 1d-массив в 2d-столбец, вы можете использовать numpy.vstack:

>>> numpy.vstack(numpy.array([1,2,3]))
array([[1],
       [2],
       [3]])

Это также работает для ванильных списков:

>>> numpy.vstack([1,2,3])
array([[1],
       [2],
       [3]])
person Colonel Panic    schedule 28.04.2017
comment
@sandroscodelller, вы смотрели код, лежащий в основе vstack? np.concatenate([atleast_2d(_m) for _m in tup], 0). Он разбивает массив на (1,1) массивы и объединяет их! В процессе он делает копию, а все измененные - вид. - person hpaulj; 03.03.2019
comment
@hpaulj Верно, но это применимо только тогда, когда вы выполняете процесс из другого массива np. Если вы используете ванильный список в качестве входных данных для vstack, недостатка в производительности нет. - person Ivan; 20.04.2021

Вы можете транспонировать только 2D-массив. Вы можете использовать numpy.matrix для создания 2D-массива. Это опоздание на три года, но я просто добавляю к возможному набору решений:

import numpy as np
m = np.matrix([2, 3])
m.T
person Jean-Louis Mbaka    schedule 18.02.2015
comment
Использование np.matrix не требуется и обычно не рекомендуется. - person hpaulj; 03.03.2019

вместо этого используйте arr[:,None] для создания вектора-столбца

person Mohammed Awney    schedule 01.09.2018

Другое решение .... :-)

import numpy as np

a = [1,2,4]

[1, 2, 4]

b = np.array([a]).T

массив ([[1], [2], [4]])

person omotto    schedule 25.04.2017
comment
В чем проблема этого решения ?! - person omotto; 26.10.2017

По сути, функция транспонирования меняет местами форму и шаги массива:

>>> a = np.ones((1,2,3))

>>> a.shape
(1, 2, 3)

>>> a.T.shape
(3, 2, 1)

>>> a.strides
(48, 24, 8)

>>> a.T.strides
(8, 24, 48)

В случае массива 1D numpy (массив ранга 1) форма и шаги являются кортежами из 1 элемента и не могут быть заменены местами, а транспонирование такого массива 1D возвращает его без изменений. Вместо этого вы можете транспонировать «вектор-строку» (массив из множества фигур (1, n)) в «вектор-столбец» (массив из множества фигур в форме (n, 1)). Для этого вам нужно сначала преобразовать массив 1D numpy в вектор-строку, а затем поменять местами форму и шаги (транспонировать). Ниже приведена функция, которая это делает:

from numpy.lib.stride_tricks import as_strided

def transpose(a):
    a = np.atleast_2d(a)
    return as_strided(a, shape=a.shape[::-1], strides=a.strides[::-1])

Пример:

>>> a = np.arange(3)
>>> a
array([0, 1, 2])

>>> transpose(a)
array([[0],
       [1],
       [2]])

>>> a = np.arange(1, 7).reshape(2,3)
>>> a     
array([[1, 2, 3],
       [4, 5, 6]])

>>> transpose(a)
array([[1, 4],
       [2, 5],
       [3, 6]])

Конечно, вам не обязательно делать это таким образом, поскольку у вас есть одномерный массив, и вы можете напрямую преобразовать его в массив (n, 1) с помощью a.reshape((-1, 1)) или a[:, None]. Я просто хотел продемонстрировать, как работает транспонирование массива.

person Andreas K.    schedule 06.01.2020
comment
это помогло мне понять, как поступить наоборот. - person D_C; 28.05.2021

Я просто консолидирую вышеуказанный пост и надеюсь, что это поможет другим сэкономить время:

В приведенном ниже массиве есть (2, )dimension, это одномерный массив,

b_new = np.array([2j, 3j])  

Есть два способа транспонировать одномерный массив:


нарежьте его с помощью "np.newaxis" или без него!

print(b_new[np.newaxis].T.shape)
print(b_new[None].T.shape)

другой способ записи, указанное выше, без T операции.!

print(b_new[:, np.newaxis].shape)
print(b_new[:, None].shape)

Обертывание [] или использование np.matrix означает добавление нового измерения.!

print(np.array([b_new]).T.shape)
print(np.matrix(b_new).T.shape)
person Anu    schedule 11.12.2018

Транспонирование

x = [[0 1],
     [2 3]]

is

xT = [[0 2],
      [1 3]]

ну код:

import numpy as np
x = np.array([[0, 1],[2, 3]]);
np.transpose(x)   

Или простой способ:

x.T     

это ссылка для получения дополнительной информации:

http://docs.scipy.org/doc/numpy/reference/generated/numpy.transpose.html

person Faeze    schedule 23.11.2014

Как упоминалось в некоторых комментариях выше, транспонированные одномерные массивы являются одномерными массивами, поэтому одним из способов транспонирования одномерного массива было бы преобразование массива в такую ​​матрицу:

np.transpose(a.reshape(len(a), 1))
person TheOriginalAlex    schedule 21.03.2016


Существует метод, не описанный в ответах, но описанный в документация для numpy.ndarray.transpose метода:

Для одномерного массива это не имеет никакого эффекта, поскольку транспонированный вектор - это просто тот же вектор. Чтобы преобразовать одномерный массив в двухмерный вектор-столбец, необходимо добавить дополнительное измерение. np.atleast2d (a) .T достигает этого, как и [:, np.newaxis].

Можно:

import numpy as np
a = np.array([5,4])
print(a)
print(np.atleast_2d(a).T)

Что (имо) лучше, чем использовать newaxis.

person Amin Karbas    schedule 29.11.2019

То, как я научился реализовывать это компактным и читаемым способом для одномерных массивов, до сих пор:

h = np.array([1,2,3,4,5])

v1 = np.vstack(h)
v2 = np.c_[h]

h1 = np.hstack(v1)
h2 = np.r_[v2[:,0]]

numpy.r_ и < strong> numpy.c_ преобразует объекты среза в конкатенацию по первой и второй осям соответственно. Следовательно, нарезка v2 [:, 0] при транспонировании вертикального массива v2 обратно в горизонтальный массив h2

numpy.vstack эквивалентно объединению по первой оси после преобразования одномерных массивов формы (N,) в (1, N). Восстанавливает массивы, разделенные vsplit.

person and-sang    schedule 21.02.2020