当我使用numpy.cross
时,它将返回包含结果的数组。无法将计算到现有数组中。其他功能也是如此。
答案 0 :(得分:2)
函数x = np.cross(x, y)
存在开销,因为它会创建一个新的NumPy数组。您可以执行if (n3 === 0) {
// show error
return;
}
for(var i = n1; n3 > 0 && i < n2 || n3 < 0 && i >= n2; i += n3) {
nArr.push(i);
}
,但不会抑制开销。
如果你有一个程序,这实际上是一个问题(例如通过分析程序来诊断),你最好转向特定的优化策略。想到the documentation和Cython。
答案 1 :(得分:1)
当前版本的np.cross
(截至1.9)需要花费大量精力来避免临时数组。尽可能使用输入视图,即使它必须滚动轴。它创建输出数组
cp = empty(shape, dtype)
然后注意使用out
multiply
和-=
种任务进行就地计算。
multiply(a0, b1, out=cp)
cp -= a1 * b0
然而,大多数这些操作仍然是缓冲的。即a1*b0
写入临时缓冲区数组,然后从cp
中减去。
通常我们不担心那些临时数组。我们让开发人员担心效率和可靠性。处理临时缓冲区是编译代码的责任,而不是我们的责任。
无缓冲的add.at
文档提供了有关缓冲与否的使用的一些见解。这种无缓冲的.at
方法用于常规缓冲版本无法处理的某些串行操作。但它并不是加速代码的一种方式。
听起来您希望np.cross
采用out
参数,认为如果可以使用
cp = np.empty(rightsize)
for a,b in zip(A,B):
np.cross(A,B,out=cp)
<use cp>
它会比
快很多for a,b, in zip(A,B):
cp = np.cross(A,B)
<use cp>
我怀疑这是否会有所帮助。在大图中,cp=np.empty(...)
是次要消费者。
但是,让我们使用np.multiply
进行时间测试,这需要out
:
In [18]: x = np.ones((1000,1000))
In [19]: %%timeit
...: y = np.multiply(x,x)
...:
100 loops, best of 3: 12.4 ms per loop
In [20]: %%timeit y = np.empty(x.shape)
...: np.multiply(x,x, out=y)
...:
100 loops, best of 3: 6.48 ms per loop
好的,从时序循环中取出分配确实将时间缩短了一半。
但是如果你反复调用np.cross
(或类似其他函数),我认为你应该更多关注重复次数而不是数组重用等细节。
np.cross(np.ones((N,3)), np.ones((N,3)))
比
快得多for i in range(N):
np.cross(np.ones(3), np.ones(3))
但是复制np.cross
(它的纯Python)很容易,并修改它以取out
。试一试,看看它是否有所作为。只要您使用正确大小的cp
它就应该有效。您必须决定是否绕过shape
行之前的dtype
和cp=empty...
检查。