像@ shx2说的,这一切都取决于什么是foo
。如果你能在numpy的ufuncs方面表达出来,然后用outer
方法:
In [11]: N = 400
In [12]: B = np.empty((N, N))
In [13]: x = np.random.random(N)
In [14]: y = np.random.random(N)
In [15]: %%timeit
for i in range(N):
for j in range(N):
B[i, j] = x[i] - y[j]
....:
10 loops, best of 3: 87.2 ms per loop
In [16]: %timeit A = np.subtract.outer(x, y) # <--- np.subtract is a ufunc
1000 loops, best of 3: 294 µs per loop
否则,您可以推动循环下来用Cython水平。继续以上一个简单的例子:
In [45]: %%cython
cimport cython
@cython.boundscheck(False)
@cython.wraparound(False)
def foo(double[::1] x, double[::1] y, double[:, ::1] out):
cdef int i, j
for i in xrange(x.shape[0]):
for j in xrange(y.shape[0]):
out[i, j] = x[i] - y[j]
....:
In [46]: foo(x, y, B)
In [47]: np.allclose(B, np.subtract.outer(x, y))
Out[47]: True
In [48]: %timeit foo(x, y, B)
10000 loops, best of 3: 149 µs per loop
的用Cython例如故意制造过于简单化:在现实中,你可能要添加一些形状/步幅检查,你的函数等
使用矢量化函数,它将使用Numpy的“外部”函数同时处理va和vb的所有元素...或传递va和vb的网格... – 2014-10-31 11:03:21
问题是此函数是自定义的,并且正在变为矢量化是不平凡的。我尝试使用'np.meshgrid',然后使用'np.vectorize',但性能改进很小。 – 2014-10-31 11:17:15
'vectorize'对你的'foo'的内部没有任何作用。这只是一个包装,而不是最终每个标量调用'foo(a,b)'。这是一种方便,而不是加速工具。 – hpaulj 2014-10-31 20:36:49