重塑任意集合numpy数组

时间:2015-04-26 15:09:30

标签: python arrays performance numpy scientific-computing

我有一个相对较小的 k N numpy数组,其中 k 的数量级为10,而 N < / em>非常大,订单为10 ^ 7。我正在尝试创建一个单独的,二维的 N x k 数组,以特定的方式捆绑这些数据。

确切地说,这是我想要做的具体例子。

x = np.array([0,0,0,0])
y = np.array([1,1,1,1])
z = np.array([2,2,2,2])

我想要的数组是:

p = np.array([[0,1,2], [0,1,2], [0,1,2], [0,1,2]])

速度是一个关键问题,因此for-looping速度慢得令人无法接受。我无法弄清楚如何使用np.reshape或np.concatenate来做到这一点,但我知道必须有一些简单的,单行的numpy语法。

4 个答案:

答案 0 :(得分:3)

您可以使用column_stack

>>> np.column_stack([x, y, z])
array([[0, 1, 2],
       [0, 1, 2],
       [0, 1, 2],
       [0, 1, 2]])

Internally这使得三个数组2D(如果可能的话,不进行复制),转换它们,然后连接它们。连接函数是一个内部C函数,因此速度可能很快。

答案 1 :(得分:1)

您可以使用domain.com/page.php

np.concatenate

此外,您可以迭代地附加数组,然后进行转置。

注意:这会产生3个循环。

In [117]: np.concatenate(([x], [y], [z]), axis=0).T
Out[117]:
array([[0, 1, 2],
       [0, 1, 2],
       [0, 1, 2],
       [0, 1, 2]])

答案 2 :(得分:1)

您可以尝试以下几种方法:

  • 使用vstack并转置:

    p = numpy.vstack((x, y, z)).T
    
  • 使用concatenatereshape

    p = numpy.concatenate((x, y, z)).reshape((3, len(x))).T
    
  • 分配新数组并使用put

    p = numpy.empty((len(x), 3))
    for i, a in enumerate((x, y, z)):
        p[:,i] = a
    

与iPython中计算的时间结果一起,len(x) == len(y) == len(z) == 1e7

In [57]: %timeit p = numpy.vstack((x, y, z)).T
10 loops, best of 3: 117 ms per loop

In [58]: %timeit p = numpy.concatenate((x, y, z)).reshape((3, len(x))).T
10 loops, best of 3: 120 ms per loop

In [60]: %timeit p = numpy.column_stack((x, y, z))
10 loops, best of 3: 159 ms per loop

In [66]: %%timeit
   ....: p = numpy.empty((len(x), 3), order='C')
   ....: for i, a in enumerate((x, y, z)):
   ....:   p[:,i] = a
   ....: 
10 loops, best of 3: 147 ms per loop

In [67]: %%timeit
   ....: p = numpy.empty((len(x), 3), order='F')
   ....: for i, a in enumerate((x, y, z)):
   ....:   p[:,i] = a
   ....: 
10 loops, best of 3: 119 ms per loop

我还包括ajcr's answer中的方法,并在最后一个中尝试了行主要和列主要排序。在时序,120ms类方法和150ms类方法方面似乎有大约两组方法,并且可能值得注意的是,行主要顺序('C')是其中之一。后一组,而列主要顺序('F')是前一组。

我怀疑这些值不够可靠,无法区分这些方法。我鼓励你做自己的测试,看看哪个是最快的。

答案 3 :(得分:0)

好的,感谢大家的帮助。正如我所怀疑的那样,正是出于这个目的,在numpy中有一个单行。 Transpose,vstack和column_stack都是对我正在做的事情的巨大速度提升。

有四种建议的解决方案,所有解决方案都返回正确的数组:

  • 连接+转置(David Z)

  • vstack (David Z)

  • 预分配+切片分配(David Z)

  • column_stack (ajcr)

以下内容的结果是:在所有制度中,连接+转置是最快的算法。

我已经对 k N 的解决方案进行了一些简单的探索,在 k~N中查找缩放政权,以及 k&lt;&lt; N 制度。但值得注意的是,即使对于非常大的 N ,运行时间也不到1秒,因此只有MCMC类型的应用程序才能真正对这类事情大惊小怪。

以下是我运行的测试摘要:

  • 首先,我可以定量地确认大卫Z的速度测试。此外,在他探索的制度中,我发现他发现的差异是强大的,而不是简单的波动。见下文。

  • k&lt;&lt; N 制度,我注意到 vstack 连接+转置之间没有明显差异。在这种情况下,无论 k N 的值如何,它们返回的时间都在1-5%之内。

  • k&lt;&lt; N 制度,我注意到 column_stack 预分配&amp;之间没有明显差异。切片分配。在这种情况下,无论 k N 的值如何,它们返回的时间都在1-5%之内。

  • k&lt;&lt; N 制度, vstack column_stack 快50-500%。该分数速度差仅随着 N 缓慢增加,但随着 k 迅速增加。 N 越大, k 的分数增加率越快。

  • k~N 制度中(与我的问题无关,但可能与其他问题无关),连接+转置是最快的,预先分配&amp;切片分配尾随10-50%。

  • k~N 制度中, column_stack vstack 的速度大致相同,为500-1000%次慢于连接+转置

所以,正如我上面所说,结果是连接+转置是所有政权中最快的:

p = np.concatenate((x, y, z)).reshape((3, len(x))).T

但是,在与原始问题相关的制度中, vstack 方法具有相同的性能,并且对语法的处理不那么严格:

p = numpy.vstack((x, y, z)).T