就地修改numpy函数输出数组
我正在尝试写一个函数,这个函数可以对一个数组进行数学运算,并返回结果。一个简单的例子可能是:
def original_func(A):
return A[1:] + A[:-1]
为了提高速度,并且避免每次调用函数时都分配一个新的输出数组,我想把输出数组作为参数传入,并在原地修改它:
def inplace_func(A, out):
out[:] = A[1:] + A[:-1]
但是,当我以以下方式调用这两个函数时,
A = numpy.random.rand(1000,1000)
out = numpy.empty((999,1000))
C = original_func(A)
inplace_func(A, out)
原来的函数似乎比这个原地修改的函数快了两倍。这怎么解释呢?难道原地修改的函数不应该更快吗?因为它不需要分配内存?
3 个回答
-1
我同意奥利弗的解释。如果你想在原地进行操作,也就是直接在数组上修改,你需要手动遍历你的数组。这样做会慢很多,但如果你需要更快的速度,可以考虑使用Cython,这样可以让你的代码运行得像纯C语言一样快。
12
如果你想在原地进行操作,可以这样做:
def inplace_func(A, out): np.add(A[1:], A[:-1], out)
这样做不会创建任何临时变量,而像 A[1:] + A[:-1]
这样的操作会创建临时变量。
所有的Numpy二元操作都有对应的函数,你可以在这里查看列表:http://docs.scipy.org/doc/numpy/reference/ufuncs.html#available-ufuncs
5
我觉得答案是这样的:
在这两种情况下,你都在计算 A[1:] + A[:-1]
,而且在这两种情况下,你实际上都会创建一个中间的矩阵。
不过在第二种情况下,你是明确地把整个新分配的大数组复制到一个预留的内存里。复制这样一个数组大约需要和最初的操作一样的时间,所以实际上你把时间加倍了。
总结一下,在第一种情况下,你做的是:
compute A[1:] + A[:-1] (~10ms)
而在第二种情况下,你做的是:
compute A[1:] + A[:-1] (~10ms)
copy the result into out (~10ms)