numpy中的vs -=运算符
我在写Python代码的时候遇到了一些奇怪的情况,主要和-
和-=
这两个符号有关。我正在用numpy做QR分解,在一个双重循环中有这样一行代码:
v = v - r[i,j] * q[:,i]
这里的q
和r
都是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 个回答
我赞同其他两个答案,它们讲到了=
和-=
之间的两个重要区别,但我想再强调一个。大多数情况下,x -= y
和x[:] = x - y
是一样的,但当x
和y
是同一个数组的切片时,就不一样了。例如:
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.]
如果 x
和 y
的数据类型不一样,使用 x - y
和 x -= 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
),特别是要注意那些在 -=
左边的数组。
当 v
是一个切片时,v -= X
和 v = 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