python - 更快的 numpy 解决方案而不是 itertools.combinations?

标签 python python-2.7 numpy optimization python-itertools

我正在使用 itertools.combinations() 如下:

import itertools
import numpy as np

L = [1,2,3,4,5]
N = 3

output = np.array([a for a in itertools.combinations(L,N)]).T

这会产生我需要的输出:

array([[1, 1, 1, 1, 1, 1, 2, 2, 2, 3],
       [2, 2, 2, 3, 3, 4, 3, 3, 4, 4],
       [3, 4, 5, 4, 5, 5, 4, 5, 5, 5]])

我在多处理环境中重复和过度地使用这个表达式,我需要它尽可能快。

来自 this post我知道基于 itertools 的代码不是最快的解决方案,使用 numpy 可能是一种改进,但是我在 numpy 方面还不够好> 优化技巧,以理解和调整那里编写的迭代代码或提出我自己的优化。

如有任何帮助,我们将不胜感激。

编辑:

L 来自 pandas dataframe,所以它也可以看作是一个 numpy 数组:

L = df.L.values

最佳答案

这是一个比 itertools UPDATE 稍微快一点的:还有一个 (nump2) 实际上要快很多:

import numpy as np
import itertools
import timeit

def nump(n, k, i=0):
    if k == 1:
        a = np.arange(i, i+n)
        return tuple([a[None, j:] for j in range(n)])
    template = nump(n-1, k-1, i+1)
    full = np.r_[np.repeat(np.arange(i, i+n-k+1),
                           [t.shape[1] for t in template])[None, :],
                 np.c_[template]]
    return tuple([full[:, j:] for j in np.r_[0, np.add.accumulate(
        [t.shape[1] for t in template[:-1]])]])

def nump2(n, k):
    a = np.ones((k, n-k+1), dtype=int)
    a[0] = np.arange(n-k+1)
    for j in range(1, k):
        reps = (n-k+j) - a[j-1]
        a = np.repeat(a, reps, axis=1)
        ind = np.add.accumulate(reps)
        a[j, ind[:-1]] = 1-reps[1:]
        a[j, 0] = j
        a[j] = np.add.accumulate(a[j])
    return a

def itto(L, N):
    return np.array([a for a in itertools.combinations(L,N)]).T

k = 6
n = 12
N = np.arange(n)

assert np.all(nump2(n,k) == itto(N,k))

print('numpy    ', timeit.timeit('f(a,b)', number=100, globals={'f':nump, 'a':n, 'b':k}))
print('numpy 2  ', timeit.timeit('f(a,b)', number=100, globals={'f':nump2, 'a':n, 'b':k}))
print('itertools', timeit.timeit('f(a,b)', number=100, globals={'f':itto, 'a':N, 'b':k}))

时间:

k = 3, n = 50
numpy     0.06967267207801342
numpy 2   0.035096961073577404
itertools 0.7981023890897632

k = 3, n = 10
numpy     0.015058324905112386
numpy 2   0.0017436158377677202
itertools 0.004743851954117417

k = 6, n = 12
numpy     0.03546895203180611
numpy 2   0.00997065706178546
itertools 0.05292179994285107

关于python - 更快的 numpy 解决方案而不是 itertools.combinations?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42138681/

相关文章:

python - 列表理解;将代码压缩为两行

python - if 语句处理操作

python - 创建 python 生成器后更新它

python - 如何使用 NumPy 生成相邻索引

python - 如何获得链式 IIR 滤波器的 b、a(分子/分母)?

PHP 与 django 一起在 heroku 实例中

java - 什么相当于python相当于使用Class.getResource()

python - 如何在python中将24色bmp图像转换为16色bmp

python - Numpy 导入抛出 AttributeError : 'module' object has no attribute 'core'

python - 使用 selenium 时出现错误 : Unable to move the cache: Access is denied,(python)