6

我正在尝试编写一个对数组执行数学运算并返回结果的函数。一个简化的例子可能是:

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)

原始功能似乎是就地功能的两倍。这怎么解释?由于不需要分配内存,就地函数不应该更快吗?

4

3 回答 3

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

于 2011-09-23T20:28:05.580 回答
5

认为答案如下:

在这两种情况下,您都计算A[1:] + A[:-1],并且在这两种情况下,您实际上都创建了一个中间矩阵。

但是,在第二种情况下,您将整个新分配的大数组显式复制到保留内存中。复制这样一个数组所花费的时间与原始操作大致相同,因此实际上您将时间加倍。

总而言之,在第一种情况下,您可以:

compute A[1:] + A[:-1] (~10ms)

在第二种情况下,你做

compute A[1:] + A[:-1] (~10ms)
copy the result into out (~10ms)
于 2011-09-23T13:58:09.480 回答
-1

我同意奥利弗斯的解释。如果要就地执行操作,则必须手动循环遍历数组。这会慢得多,但如果您需要速度,您可以求助于 Cython,它为您提供纯 C 实现的速度。

于 2011-09-23T15:34:28.643 回答