Python 如何在不隐藏额外内存分配的情况下就地修改numpy数组?
我有一个函数,它必须用f(x)替换numpy数组x的每个元素x 但这不起作用:Python 如何在不隐藏额外内存分配的情况下就地修改numpy数组?,python,arrays,numpy,Python,Arrays,Numpy,我有一个函数,它必须用f(x)替换numpy数组x的每个元素x 但这不起作用: >>> X = numpy.random.random( size=(2,3) ) >>> X array([[ 0.97476386, 0.76411101, 0.37690288], [ 0.05462798, 0.44722799, 0.23570353]]) >>>> modify_inplace(X) >>>
>>> X = numpy.random.random( size=(2,3) )
>>> X
array([[ 0.97476386, 0.76411101, 0.37690288],
[ 0.05462798, 0.44722799, 0.23570353]])
>>>> modify_inplace(X)
>>> X
array([[ 0.97476386, 0.76411101, 0.37690288],
[ 0.05462798, 0.44722799, 0.23570353]])
我知道,我可以简单地返回新的数组,但我想知道是否可以修改原地的numpy数组,这样就不会分配额外的内存了
Ashwini Chaudhary在下面提供了一个解决方案,但这并不是我想要的,因为我需要在没有任何额外malloc的情况下修改数组。目前,您只需创建一个新的局部变量
X
,并为其分配一个新值,要更新函数中由X
指向的对象,请使用切片分配[:]:
>>> def modify_inplace(X):
X[:] = 2. / (8. + numpy.exp(-X))
...
>>> X = numpy.random.random( size=(2,3))
>>> X
array([[ 0.21210661, 0.03573271, 0.07002263],
[ 0.77282535, 0.13973994, 0.82784145]])
>>> modify_inplace(X)
>>> X
array([[ 0.22704366, 0.22309233, 0.22390467],
[ 0.23635894, 0.22548971, 0.23705132]])
这种情况下的真正就地方法可以是:
def modify_inplace(X):
np.exp(X, out=X)
X += 8.
np.power(X, -1, out=X)
X *= 2
与@Ashwini Chaudhary的方法相比,有两个主要优势(这也是很好的):
- 不需要分配新阵列
- 操作后无需复制任何数据
编辑: 请注意,对于
X
多次出现的更复杂表达式,很难避免复制,例如:
(X + 2.)/(8. + np.exp(X))
这里,当您将
X
更改为计算np.exp(X)
时,计算表达式的其余部分将不再有效…谢谢。因此,在这种情况下,Numpy不会分配任何额外的存储空间?@psihodelia对于您的情况,将首先在内存中创建一个新数组,然后用该数组替换原始数组的内容。之后,新数组将被垃圾收集,因为不再有对它的引用。但这意味着此数组不会在原地修改。我的问题是如何避免内存分配和修改数组-就像在C中一样。无论如何,谢谢你。@psihodelia如果你想这样做,是O(1)个额外的内存,那么你必须用一个简单的循环替换RHS上的表达式,然后在循环过程中,用迭代中生成的值更新X中的当前项。谢谢。在使用两个X的第二个示例中,还有什么解决方案可以避免内存分配?@psihodelia在这种情况下,我只看到在数组上循环计算临时变量中表达式的答案并替换旧值。。。例如,可以在Cython中完成
(X + 2.)/(8. + np.exp(X))