Python 理解numpy中的内存分配:Is";“临时”;将操作结果存储到变量[:,:]时分配的内存?

Python 理解numpy中的内存分配:Is";“临时”;将操作结果存储到变量[:,:]时分配的内存?,python,python-3.x,numpy,memory-management,Python,Python 3.x,Numpy,Memory Management,让我们假设两个大的多维numpy数组a和b。我想执行元素操作,例如,逐元素添加它们: c = a + b 在上述情况下,将为a+b的结果分配新内存。然后,对该内存的引用存储在c中 现在,让我们假设c的内存已经分配。为了有一个简单的示例,将维度数设置为2,我可以执行以下操作: c[:, :] = a + b 我找不到任何关于如何准确实施上述内容的文件。我可以想象两种方式: 首先,分配内存以执行操作a+b。在将数据(即操作结果)复制到c[:,:]之前,将结果存储到该“临时”内存中 没有分配临时内

让我们假设两个大的多维numpy数组
a
b
。我想执行元素操作,例如,逐元素添加它们:

c = a + b
在上述情况下,将为
a+b
的结果分配新内存。然后,对该内存的引用存储在
c

现在,让我们假设
c
的内存已经分配。为了有一个简单的示例,将维度数设置为2,我可以执行以下操作:

c[:, :] = a + b
我找不到任何关于如何准确实施上述内容的文件。我可以想象两种方式:

  • 首先,分配内存以执行操作
    a+b
    。在将数据(即操作结果)复制到
    c[:,:]
    之前,将结果存储到该“临时”内存中
  • 没有分配临时内存。
    a+b
    的结果直接进入
    c[:,:]

  • 我使用了一些代码,在性能方面,我觉得第一个选项更有可能。我说得对吗?如果是这样,我如何避免分配“临时内存”,并将结果直接存储到
    c
    中已有的内存中?我想我必须更加明确,使用像
    numpy.add
    这样的函数,并向它们提供对目标内存的引用。

    您正在寻找的操作是

    numpy.add(a, b, out=c)
    
    使用
    c[:,:]=a+b
    ,对
    a+b
    的评估没有关于结果将被分配给
    c[:,:]
    的信息。它必须分配一个新数组来保存
    a+b
    的结果


    (最新版本的NumPy确实尝试执行一些主动优化临时性的操作,超出了Python执行模型通常允许的范围,但这些优化无法处理这种情况。您可以在中看到代码,包括一些关于它在什么平台上工作以及为什么Python堆栈检查不够的注释。)

    您正在寻找的操作是

    numpy.add(a, b, out=c)
    
    使用
    c[:,:]=a+b
    ,对
    a+b
    的评估没有关于结果将被分配给
    c[:,:]
    的信息。它必须分配一个新数组来保存
    a+b
    的结果


    (最新版本的NumPy确实尝试执行一些主动优化临时性的操作,超出了Python执行模型通常允许的范围,但这些优化无法处理这种情况。您可以在中看到代码,包括一些关于它在什么平台上工作以及为什么Python堆栈检查不够的注释。)

    这是第一个,因为Python是如何从左到右计算的。。。虽然numpy可以做一些奇特的事情,但它不能覆盖Python计算语句的机制…@JonClements是的,我猜是这样的。。。我不知道如何以另一种方式实现
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
    。。。虽然numpy可以做一些奇特的事情,但它不能覆盖Python计算语句的机制…@JonClements是的,我猜是这样的。。。我不知道如何以另一种方式实现
    \uuuu添加\uuuu
    。是的。。。RHS上的对象不知道它被绑定到什么(如果它被绑定的话),所以唯一的方法就像你在这里使用
    numpy.add(a,b,out=c)
    所说的那样,在这里它明确地给出了一些空间,它可以在其中工作,而不必假设它必须为结果构建自己的数组。(我倾向于认为这就像使用C的
    memcpy
    之类的东西,而不是一个
    malloc
    操作)感谢您的快速回复,这很有意义。我只是想知道(或不是)是否有一些我不知道的黑色Python魔法:)表达式,如
    np.add(A[:,1:,A[:,:-1],out=A[:,1:)
    建议,即使使用
    out
    numpy
    创建一个临时缓冲区。@hpaulj:numpy仅在认为有必要复制以处理重叠的输入和输出时,才为此类操作制作副本。对于像
    add(a,b,out=c)
    这样没有重叠的东西,它不会复制。(安全副本是NumPy 1.13.0)是的。。。RHS上的对象不知道它被绑定到什么(如果它被绑定的话),所以唯一的方法就像你在这里使用
    numpy.add(a,b,out=c)
    所说的那样,在这里它明确地给出了一些空间,它可以在其中工作,而不必假设它必须为结果构建自己的数组。(我倾向于认为这就像使用C的
    memcpy
    之类的东西,而不是一个
    malloc
    操作)感谢您的快速回复,这很有意义。我只是想知道(或不是)是否有一些我不知道的黑色Python魔法:)表达式,如
    np.add(A[:,1:,A[:,:-1],out=A[:,1:)
    建议,即使使用
    out
    numpy
    创建一个临时缓冲区。@hpaulj:numpy仅在认为有必要复制以处理重叠的输入和输出时,才为此类操作制作副本。对于像
    add(a,b,out=c)
    这样没有重叠的东西,它不会复制。(安全副本为NumPy 1.13.0版本。)