【问题标题】:Avoid creating new arrays as results for numpy/scipy operations?避免创建新数组作为 numpy/scipy 操作的结果?
【发布时间】:2015-04-26 02:14:24
【问题描述】:

对于在 numpy/scipy 中进行重复操作,有很多开销,因为大多数操作返回一个新对象。

例如

for i in range(100):
   x = A*x

我想通过传递对操作的引用来避免这种情况,就像在 C 中一样

for i in range(100):
   np.dot(A,x,x_new) #x_new would now store the result of the multiplication
   x,x_new = x_new,x

有没有办法做到这一点?我希望这不仅仅是为了乘法,而是为了所有返回矩阵或向量的操作。

【问题讨论】:

  • 查看函数的文档。有些采用out 参数,尤其是ufunc 参数。基本运算符有+=、*= 等版本。 ufuncs 也有 reduce 和 accumulate 处理重复动作的方法。
  • 您使用np.dot 给出的示例代码已经做到了这一点——np.dot 的第三个参数是out= 参数,所以x_new 将用@ 的结果填充987654334@
  • 您可能还想考虑np.dot(np.linalg.matrix_power(A, 100), x)。
  • 请注意,在大多数情况下,您认为存在“大量开销”的直觉是不正确的。与矩阵乘法本身所需的计算相比,创建新的 Python 对象或分配内存块的成本更低。

标签: python numpy memory-management optimization scipy


【解决方案1】:

请参阅 IPython 书籍中的 Learning to avoid unnecessary array copies。从那里,注意例如这些准则:

a *= b

不会生成副本,而:

a = a * b

将制作一份副本。此外,flatten() 将复制,而ravel() 仅在必要时复制,否则返回视图(因此通常应该是首选)。 reshape() 也不会产生副本,而是返回一个视图。

此外,正如 @hpaulj 和 @ali_m 在他们的 cmets 中指出的那样,许多 numpy 函数支持 out 参数,因此请查看文档。来自numpy.dot() docs:

out : ndarray,可选 输出参数。

这必须与不使用时返回的确切类型相同。特别是,它必须具有正确的类型,必须是 C 连续的,并且它的 dtype 必须是将为 dot(a,b) 返回的 dtype。这是一个性能特征。因此,如果不满足这些条件,则会引发异常,而不是尝试灵活处理。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-03
    • 2019-10-08
    • 2016-06-06
    相关资源
    最近更新 更多