以下是从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)
非常大,并且numpy
为A[:, idx1, idx2]
生成一些内部数组,那么可以想象一下,它不具有内存效率。有没有更好的方法来做这件事?
答案 0 :(得分:2)
这个表达式由Python解释器解析和评估:
B = np.prod(A[:, idx1, idx2], axis=2)
首先它
temp = A[:, idx1, idx2] # expands to:
temp = A.__getitem__(slice(None), idx1, idx2)
由于idx1
,idx2
是数组,因此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数组没有等效。