numpy中的vs -=运算符

19 投票
3 回答
5641 浏览
提问于 2025-04-17 11:18

我在写Python代码的时候遇到了一些奇怪的情况,主要和--=这两个符号有关。我正在用numpy做QR分解,在一个双重循环中有这样一行代码:

v = v - r[i,j] * q[:,i]

这里的qr都是numpy.array类型的,而v是从另一个numpy.array中切片得到的,具体是v = x[:,j]

上面的代码在某些情况下并没有按预期工作。不过,如果我做如下修改:

v -= r[i,j] * q[:,i]

那么一切就能顺利运行了。

我原以为这两行代码应该是一样的。为了测试-=_ = _ -是否有不同的效果,我写了以下代码片段:

import numpy

x = numpy.array(range(0,6))
y = numpy.array(range(0,6))

u = x[3:5]
v = y[3:5]

print u,v

u = u - [1,1]
v -= [1,1]

print u,v

结果也如预期那样,在两个打印语句中都输出了[2 3] [2 3]

所以我完全搞不懂为什么这两行的表现会不同。我能想到的唯一可能性是,有时候我处理的数字非常小(大约在10^-8或更小),可能-=在处理精度问题上更好一些?第一行的表现随着x的元素变小而越来越差。

如果之前有类似的问题,我很抱歉,我无法搜索--=,也不知道除了赋值/运算符之外还有什么正确的术语。

谢谢大家的帮助!

3 个回答

5

我赞同其他两个答案,它们讲到了=-=之间的两个重要区别,但我想再强调一个。大多数情况下,x -= yx[:] = x - y是一样的,但当xy是同一个数组的切片时,就不一样了。例如:

x = np.ones(10)
y = np.ones(10)

x[1:] += x[:-1]
print x
[  1.   2.   3.   4.   5.   6.   7.   8.   9.  10.]

y[1:] = y[1:] + y[:-1]
print y
[ 1.  2.  2.  2.  2.  2.  2.  2.  2.  2.]
14

如果 xy 的数据类型不一样,使用 x - yx -= y 可能会得到不同的结果。

举个例子:

import numpy as np

x = np.array(range(0,6))
y = np.array(np.arange(0,3,0.5))

print x - y
x -= y
print x

这段代码会输出:

[ 0.   0.5  1.   1.5  2.   2.5]
[0 0 1 1 2 2]

所以,确保你的数组的 dtypes 和你预期的一样是很重要的(比如,你可能不小心用了整数数组或 float32 数组,而不是 float64),特别是要注意那些在 -= 左边的数组。

28

v 是一个切片时,v -= Xv = v - X 的结果会有很大的不同。我们来看一下

>>> x = np.arange(6)
>>> v = x[1:4]
>>> v -= 1
>>> v
array([0, 1, 2])
>>> x
array([0, 0, 1, 2, 4, 5])

在这里,v -= 1 会直接更新这个切片,也就是它所指向的数组,直接在原地修改。而

>>> x = np.arange(6)
>>> v = x[1:4]
>>> v = v - 1
>>> v
array([0, 1, 2])
>>> x
array([0, 1, 2, 3, 4, 5])

v = v - 1 则是重新给 v 赋值,但不会改变 x 的内容。如果你想要得到和 v -= 1 一样的效果,但又不想用 -=,你需要这样做

v[:] = v - 1

撰写回答