0

我正在尝试执行以下操作。

我有两个二维数组,X 和 Y。每个都是 100x100 个元素。我想将它们线性化/展平为 10,000x1 列,然后将它们连接起来,所以我只剩下一个 10,000x2 的矩阵。在 MATLAB 中,我可以执行以下操作

BigMatrix = [X(:) Y(:)]

我想在 Python 中做同样的事情。在玩了一会儿之后,我已经能够复制 MATLAB 结果,尽管方式非常冗长,如下所示。有没有更好、更简洁的方法来实现这一点?

BigMatrix = np.concatenate(
    (X.reshape((10000,1), order = 'F'), 
     Y.reshape((10000,1), order = 'F')),
      axis=1)
4

2 回答 2

1

有多种方法可以实现您想要的,而您所拥有的完全有效。但是,您可能会发现其他一些方法更“简洁”。

使用np.ndarray.flatten

返回折叠成一维的数组的副本。

您还可以指定是否将其视为列专业或行专业。

为了获得您想要的结果(amx 2 矩阵,每个展平矩阵作为一列),您可以使用numpy.column_stack

BigMatrix = np.column_stack([X.flatten(order = 'F'), Y.flatten(order = 'F')])

或者,如果您正在寻找真正简洁的内容,正如@ssp 所提到的,您可以使用numpy 索引例程(基本上为切片提供特殊行为)。有两个用于连接,每个轴一个。r_是按行(第一个轴)和c_按列(第二个轴),所以要得到你的 mx 2 矩阵,你可以这样做:

BigMatrix = np.c_[X.flatten(order = 'F'), Y.flatten(order = 'F')]

表现?

正如@hpaulj 建议的那样,就性能而言,使用原始代码可能会更好。这是三种方法的简单时序,其中每种方法针对 100x100 大小的矩阵执行 100 万次。

from timeit import timeit

print("c_ w/ flatten", timeit(
    setup="import numpy as np\nX=np.random.standard_normal((100,100))\nY=np.random.standard_normal((100,100))",
    stmt="Z=np.c_[X.flatten(order='F'), Y.flatten(order='F')]"
))

print("column_stack w/ flatten", timeit(
    setup="import numpy as np\nX=np.random.standard_normal((100,100))\nY=np.random.standard_normal((100,100))",
    stmt="Z=np.column_stack((X.flatten(order='F'), Y.flatten(order='F')))"
))

print("concatenate w/ reshape", timeit(
    setup="import numpy as np\nX=np.random.standard_normal((100,100))\nY=np.random.standard_normal((100,100))",
    stmt="Z=np.concatenate((X.reshape((10000,1),order='F'), Y.reshape((10000,1),order='F')), axis=1)"
))

我们得到

c_ w/ flatten            44.47710300699691
column_stack w/ flatten  29.201319813000737
concatenate w/ reshape   27.67507728200144

令人惊讶的是,column_stack 和 flatten 具有可比性,而索引例程则明显较慢。

(如果我在此性能分析中遗漏了什么,请告诉我。我不是性能专家)。

于 2021-02-04T03:40:05.690 回答
1

使用小型 2 数组:

In [404]: x = np.arange(4).reshape(2,2)

reshape阶 F 是 MATLAB(:)索引的最直接等价物,产生一个 (n,1) 数组。(是x(:).'(1,n) 矩阵的语法吗?)

In [405]: x1 = x.reshape((4,1),order='F')
In [406]: x
Out[406]: 
array([[0, 1],
       [2, 3]])
In [407]: x1
Out[407]: 
array([[0],
       [2],
       [1],
       [3]])

加入两个这样的“列向量”很容易:

In [408]: np.concatenate((x1,x1), axis=1)
Out[408]: 
array([[0, 0],
       [2, 2],
       [1, 1],
       [3, 3]])

np.stack是一个concatenate创建新维度并加入其中的版本。和axis=0它一样np.array((x,x))

In [409]: np.stack((x,x), axis=2)
Out[409]: 
array([[[0, 0],
        [1, 1]],

       [[2, 2],
        [3, 3]]])

一个 order F reshape 像以前一样创建 2 列数组:

In [411]: np.stack((x,x), axis=2).reshape((-1,2),order='F')
Out[411]: 
array([[0, 0],
       [2, 2],
       [1, 1],
       [3, 3]])

或使用默认顺序:

In [412]: np.stack((x,x), axis=2).reshape((-1,2))
Out[412]: 
array([[0, 0],
       [1, 1],
       [2, 2],
       [3, 3]])

numpy是一个 Python 包,使用函数、索引和方法。它不会改变或添加到基本的 Python 语法。

于 2021-02-04T08:51:17.170 回答