如何在`numpy`数组的索引视图上提高数组操作的效率?

时间:2017-11-26 02:42:17

标签: python arrays numpy

以下是从B计算数组A的示例代码:

import numpy as np
idx1 = np.array([
 [3, 0, 0],
 [2, 1, 0],
 [2, 0, 1],
 [1, 2, 0],
 [1, 1, 1],
 [1, 0, 2],
 [0, 3, 0],
 [0, 2, 1],
 [0, 1, 2],
 [0, 0, 3]])
idx2 = np.arange(3)
A = np.arange(10*4*3).reshape(10, 4, 3)
B = np.prod(A[:, idx1, idx2], axis=2)

注意这一行

B = np.prod(A[:, idx1, idx2], axis=2)

这行内存有效吗?或者numpy会为A[:, idx1, idx2]生成一些内部数组吗?

如果len(A)非常大,并且numpyA[:, idx1, idx2]生成一些内部数组,那么可以想象一下,它不具有内存效率。有没有更好的方法来做这件事?

1 个答案:

答案 0 :(得分:2)

这个表达式由Python解释器解析和评估:

B = np.prod(A[:, idx1, idx2], axis=2)

首先它

temp = A[:, idx1, idx2]   # expands to:
temp = A.__getitem__(slice(None), idx1, idx2)

由于idx1idx2是数组,因此advanced indexing,而temp是副本,而不是视图。

接下来,解释执行:

np.prod(temp, axis=2)

也就是说,它将临时数组传递给prod函数,该函数然后返回一个数组,该数组被分配给B变量。

我不知道缓冲prod有多少。我可以想象它设置一个nditer(c-api版本),它接受两个操作数数组,temp和一个正确形状的输出(temp.shape(:-1),假设总和在最后一个维度temp)。请参阅我在The `out` arguments in `numpy.einsum` can not work as expected中引用的文档的reduction部分。

总而言之,Python在评估函数时,首先计算所有参数,然后将它们传递给函数。使用生成器可以延迟对列表的评估,但是对于numpy数组没有等效。