Numpy 与组合生成器:如何加速组合?

Posted

技术标签:

【中文标题】Numpy 与组合生成器:如何加速组合?【英文标题】:Numpy with Combinatoric generators: How does one speed up Combinations? 【发布时间】:2013-01-23 04:16:02 【问题描述】:

据我了解itertools functionsare written in C。如果我想加快这个示例代码的速度:

import numpy as np
from itertools import combinations_with_replacement

def combinatorics(LargeArray):
     newArray = np.empty((LargeArray.shape[0],LargeArray.shape[0]))
     for x, y in combinations_with_replacement(xrange(LargeArray.shape[0]), r=2):
         z = LargeArray[x] + LargeArray[y]
         newArray[x, y] = z
     return newArray

既然combinations_with_replacement 是用C 编写的,这是否意味着它不能被加速?请指教。

提前致谢。

【问题讨论】:

【参考方案1】:

combinations_with_replacement 确实是用 C 语言编写的,这意味着您不太可能加快该部分代码的实现速度。但是您的大部分代码并没有花在寻找组合上:它在 for 循环中进行添加。当你使用 numpy.这个版本几乎可以做同样的事情,通过the magic of broadcasting:

def sums(large_array):
    return large_array.reshape((-1, 1)) + large_array.reshape((1, -1))

例如:

>>> ary = np.arange(5).astype(float)
>>> np.triu(combinatorics(ary))
array([[ 0.,  1.,  2.,  3.,  4.],
       [ 0.,  2.,  3.,  4.,  5.],
       [ 0.,  0.,  4.,  5.,  6.],
       [ 0.,  0.,  0.,  6.,  7.],
       [ 0.,  0.,  0.,  0.,  8.]])
>>> np.triu(sums(ary))
array([[ 0.,  1.,  2.,  3.,  4.],
       [ 0.,  2.,  3.,  4.,  5.],
       [ 0.,  0.,  4.,  5.,  6.],
       [ 0.,  0.,  0.,  6.,  7.],
       [ 0.,  0.,  0.,  0.,  8.]])

不同之处在于combinatorics 将下三角形保留为随机乱码,其中sums 使矩阵对称。如果您真的想避免将所有内容添加两次,您可能可以,但我想不出该怎么做。

哦,还有另一个区别:

>>> big_ary = np.random.random(1000)
>>> %timeit combinatorics(big_ary)
1 loops, best of 3: 482 ms per loop
>>> %timeit sums(big_ary)
1000 loops, best of 3: 1.7 ms per loop

【讨论】:

嗯,加法实际上只是一个简单的例子;但是我能够将您的概念应用于我的现实问题,并且速度的差异就像白天和黑夜。非常感谢!

以上是关于Numpy 与组合生成器:如何加速组合?的主要内容,如果未能解决你的问题,请参考以下文章

numpy的简单使用

如何从Python中列表的dict中的值生成所有组合

Itertools 生成加扰组合

使用numpy构建两个数组的所有组合的数组

Matlab 生成所有可能的团队组合

如何动态组合生成器?