转置一维 NumPy 数组

Posted

技术标签:

【中文标题】转置一维 NumPy 数组【英文标题】:Transposing a 1D NumPy array 【发布时间】:2011-08-22 17:08:03 【问题描述】:

我使用 Python 和 NumPy,但在“转置”方面存在一些问题:

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

调用a.T 不会转置数组。如果a 是例如[[],[]] 那么它转置正确,但我需要[...,...,...] 的转置。

【问题讨论】:

也试过“print a.transpose”,但没有成功,不是转置... 我已经得出结论 Python 不像 Matlab 那样“数学化”,这就是为什么这个结果看起来很奇怪(我有 Matlab 背景,对我来说也很奇怪) 【参考方案1】:

要像您在示例中那样转置一维数组(平面数组),您可以使用 np.expand_dims() 函数:

>>> a = np.expand_dims(np.array([5, 4]), axis=1)
array([[5],
       [4]])

np.expand_dims() 将为所选轴添加一个维度。在这种情况下,我们使用axis=1,它添加了一个列维度,有效地转置了您的原始平面数组。

【讨论】:

【参考方案2】:

转置

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

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

代码如下:

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

或者简单的方法:

x.T     

此链接了解更多信息:http://docs.scipy.org/doc/numpy/reference/generated/numpy.transpose.html

** 转置一维数组会返回原始数组的未更改视图。试试这个一维数组:

b = np.array([a])

【讨论】:

【参考方案3】:

到目前为止,我已经学会了以紧凑且可读的方式为一维数组实现这一点的方式:

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_numpy.c_ 将切片对象分别转换为沿第一和第二轴的连接。因此,切片 v2[:,0] 将垂直数组 v2 转回到水平数组 h2

numpy.vstack 相当于将形状为 (N,) 的一维数组重新整形为 (1,N) 后沿第一个轴的串联。重建除以 vsplit 的数组。

【讨论】:

【参考方案4】:

转置函数的作用基本上是交换数组的形状和步幅:

>>> 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 数组(rank-1 数组)的情况下,shape 和 strides 是 1 元素元组并且不能交换,并且这种 1D 数组的转置返回它不变。相反,您可以将“行向量”(形状为(1, n) 的numpy 数组)转换为“列向量”(形状为(n, 1) 的numpy 数组)。为此,您必须首先将 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]])

当然,您不必这样做,因为您有一个一维数组,您可以通过a.reshape((-1, 1))a[:, None] 直接将其整形为(n, 1) 数组。我只是想演示转置数组的工作原理。

【讨论】:

这帮助我弄清楚如何做相反的事情。【参考方案5】:

改为使用arr[:,None] 创建列向量

【讨论】:

【参考方案6】:

有一种方法未在答案中描述,但在documentation 中描述了numpy.ndarray.transpose 方法:

对于一维数组,这没有影响,因为转置向量只是相同的向量。要将一维数组转换为二维列向量,必须添加一个额外的维度。 np.atleast2d(a).T 实现了这一点,a[:, np.newaxis] 也是如此。

可以做到:

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

哪个 (imo) 比使用 newaxis 更好。

【讨论】:

【参考方案7】:

对于一维数组

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

【讨论】:

请注意,这只适用于向量。如果您有二维数组,则操作transposereshape 以不同方式修改数组(生成的图像形状相同,但元素放置不同)。 感谢您的评论。我明白你的意思,但我认为它更分散了我​​的注意力,而不是澄清了我的答案,因为我确实为@thaking 提出的确切问题提供了一个简单的单行解决方案。这不是关于二维数组,而是关于一维数组。这里有苹果和梨。 当然。对于这种情况,您的回答是正确而优雅的,我从未打算批评它。但鉴于问题标题(“转置 NumPy 数组”),我怀疑许多访问者会来这里寻找更通用的解决方案,我想警告他们它不适用于 2D 数组。否则,鉴于 OP 的问题,您的答案是正确且合适的。 @UlfAslak,请更新您的答案,即您的方法不能推广到 ND 数组,按照 !johndodo 的建议提前明确总是好的,这样任何人都不应错误地使用您的技术。!,这里的问题是正确答案而不是班轮。!【参考方案8】:

我只是在整理上面的帖子,希望它可以帮助其他人节省一些时间:

下面的数组有(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)

【讨论】:

【参考方案9】:

它的工作方式完全符合预期。 1D 数组的转置仍然是 1D 数组! (如果你用过matlab,它基本上没有一维数组的概念。Matlab 的“一维”数组是二维的。)

如果你想把你的一维向量变成一个二维数组然后转置它,只需用np.newaxis(或None,它们是一样的,newaxis 更具可读性)对其进行切片。

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

不过,一般来说,您不必担心这一点。如果您只是出于习惯,添加额外的维度通常不是您想要的。 Numpy 在进行各种计算时会自动广播一维数组。当你只需要一个向量时,通常不需要区分行向量和列向量(它们都不是向量。它们都是二维的!)。

【讨论】:

@thaking - 我刚刚使用np.arange 快速制作一维数组。对于a = np.array([5,4]),它的工作原理完全相同。 @thaking 如果您是 numpy 新手 - 请记住圆括号 () 并不表示 numpy 中的附加维度。如果a = np.arange(10)aarray([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),由a.__repr__() 生成。这是一个一维(即a.ndim --&gt; 1)向量,如方括号[] 所示。当您执行print(a)a.__str__() 时,不会看到array( ... ) @JoeKington 有一种情况,一维数组的广播很有用。计算数组中所有一维点之间的距离。感谢您的解决方案,可以执行 x - x[np.newaxis].T 给出距离矩阵 就个人而言,我发现np.vstack() 操作更明确:print np.vstack(a) 不只是matlab,线性代数有行/列向量的概念。 Numpy 对于来自很多地方的人来说是特殊的,而不仅仅是 matlab。【参考方案10】:

要将一维数组“转置”为二维列,您可以使用numpy.vstack

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

它也适用于普通列表:

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

【讨论】:

@sandroscodelller,你看过vstack的底层代码吗? np.concatenate([atleast_2d(_m) for _m in tup], 0)。它将数组拆分为 (1,1) 数组,并将它们连接起来!在此过程中,它会制作一个副本,而所有的 reshape 都会制作一个视图。 @hpaulj 是的,但这仅适用于您从另一个 np 数组执行该过程时。如果您使用原版列表作为 vstack 的输入,那么它不会缺少性能,因为它更清晰。【参考方案11】:

另一种解决方案.... :-)

import numpy as np

a = [1,2,4]

[1,2,4]

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

数组([[1], [2], [4]])

【讨论】:

这个解决方案有什么问题?!【参考方案12】:

numpy 中的函数名称是column_stack。

>>>a=np.array([5,4])
>>>np.column_stack(a)
array([[5, 4]])

【讨论】:

【参考方案13】:

正如上面提到的一些 cmets,一维数组的转置是一维数组,因此转置一维数组的一种方法是将数组转换为矩阵,如下所示:

np.transpose(a.reshape(len(a), 1))

【讨论】:

【参考方案14】:

使用两对括号而不是一对。这将创建一个可以转置的二维数组,这与使用一对括号创建的一维数组不同。

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)

【讨论】:

我更喜欢这个解决方案而不是 [np.newaxis] 一个,它看起来更优雅。 机器没有那么智能。即使你只有一个妻子,也应该宣布为你的第一任妻子。 这应该是选择的答案 @bruno,Joe Kington 准确地回答了这个问题。 Savagent 的回答尖锐而有用,但它解释了其他东西【参考方案15】:

您只能转置二维数组。您可以使用numpy.matrix 创建一个二维数组。这已经晚了三年,但我只是在添加可能的解决方案:

import numpy as np
m = np.matrix([2, 3])
m.T

【讨论】:

不需要使用np.matrix,一般不鼓励使用。【参考方案16】:

numpy 一维数组 --> 列/行矩阵:

>>> 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 以提高可读性。

【讨论】:

【参考方案17】:

您可以将现有向量转换为矩阵,方法是将其包装在一组额外的方括号中...

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

numpy 还有一个matrix 类(参见array vs. matrix)...

matrix(v).T ## transpose a vector into a matrix

【讨论】:

矩阵类很快就会被弃用,对吧?

以上是关于转置一维 NumPy 数组的主要内容,如果未能解决你的问题,请参考以下文章

numpy array转置与两个array合并

python - numpy基础

Numpy_构建列向量

numpy数组转置与轴变换

将数组进行转置

Numpy 的数组转置和轴对换