1

我编写了一个脚本来对我们的本地集群进行一些排名顺序相关性计算。计算涉及查看两个数组,X长度Y为 5000-10000,并提取数量

all((X[i], Y[i]))
all((X[i], not Y[i]))
all((not X[i], Y[i]))

数千次计算(因为我洗牌X/Y除其他外)。

我们的一个集群正在运行 python2.4,所以我将alls 更改为numpy.alls。然而,我估计需要大约 5-6 小时的计算达到了 24 小时以上。这促使我进行调查。

这是一些示例代码:

In [2]: import timeit
In [3]: s = """import numpy as np
   ...: x, y = np.random.rand(1000), np.random.rand(1000)
   ...: [all((x[i], y[i])) for i in range(1000)]
   ...: """
In [4]: timeit.timeit(s, number=1000)
Out[4]: 0.39837288856506348

In [5]: s_numpy = """import numpy as np
   ...: x, y = np.random.rand(1000), np.random.rand(1000)
   ...: [np.all((x[i], y[i])) for i in range(1000)]
   ...: """
In [9]: timeit.timeit(s_numpy, number=1000)
Out[9]: 14.641073942184448

任何线索为什么numpy.all需要 50 倍的时间来计算这个?是numpy.array开销吗?

编辑:我的原始数组numpy.array不像他们在这里(np.random.rand)。all在我需要更改线路之前,我什至根本没有使用 numpy 。但是,我已经用类似的东西替换了我的循环

np.sum(np.logical_and(X, Y))
np.sum(np.logical_and(X, np.logical_not(Y)))
np.sum(np.logical_and(np.logical_not(X), Y))

这将初始开销的运行和大约 3000 个这些循环的计算速度提高了 60% 左右。谢谢!我将寻找更多使用 numpy 进行优化的方法。

4

2 回答 2

5
[np.all((x[i], y[i])) for i in range(1000)]

可以改写为

x = []
for i in range(1000):
    x.append(numpy.all((x[i],y[i])))

所以你在一个非常小的列表上调用 numpy.all

numpy 方法通常在更大的列表上大放异彩

timeit.timeit('all(x)','x = numpy.arange(1,100000)',number=1)
#~.0175
timeit.timeit('numpy.all(x)','x = numpy.arange(1,100000)',number=1)
#~.00043
于 2013-08-08T18:45:40.933 回答
0

通过使用生成器推导而不是列表推导,您可以使这两个函数更快、更具可比性。

s = """
import numpy as np; 
x, y = np.random.rand(1000),np.random.rand(1000);     
(all((x[i], y[i])) for i in range(1000)) """

timeit.timeit(s,number=1000)
0.05593514442443848

s_yours = """
import numpy as np; 
x, y = np.random.rand(1000),  np.random.rand(1000);
[all((x[i], y[i])) for i in range(1000)] """

timeit.timeit(s_yours,number=1000)
0.3829691410064697


s_numpy = """import numpy as np; 
x, y = np.random.rand(1000), np.random.rand(1000); 
(np.all((x[i], y[i])) for i in range(1000))"""

timeit.timeit(s_numpy,number=1000)
0.06155896186828613

s_your_numpy = """import numpy as np; 
x, y = np.random.rand(1000), np.random.rand(1000); 
[np.all((x[i], y[i])) for i in range(1000)]"""

timeit.timeit(s_your_numpy,number=1000)
12.162676811218262

Numpy 可能仍然较慢,但就像那个人说的,在更大的列表上效果更好。

还有,为什么

x.all(), y.all() 

不是一个选择?

于 2013-08-08T18:55:27.540 回答