2012-01-28 60 views
12

我在我的Python代碼中有一些奇怪的行爲,與--=相關。我正在寫使用numpy的QR分解,並有下面的代碼行的雙循環:- vs - =運算符與numpy

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

其中qr都是numpy.array,並v是作爲v = x[:,j]的另一numpy.array片。

上述代碼在所有情況下都無法按預期工作。但是,如果我做了以下更改:

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元素變小,第一行表現越來越差。

我很抱歉,如果有關於這個類似問題的任何其他帖子,我不能搜索--=,我不知道這些除了賦值/操作符之外是否有任何正確的術語。

感謝您的幫助!

+4

爲了將來的參考,如果你想要搜索這樣的東西,'-'和' - ='的名字是['__sub__'] [1]和['__isub__'] [2]分別。所以: 'a = a-b'相當於'a = a .__ sub __(b)' 'a - = b'相當於'a .__ isub __(b)'。 (除非__isub__沒有定義,那麼它就會回到上面) [1]:http://pyref.infogami.com/__add__ [2]:http://pyref.infogami.com/__iadd__ – 2012-01-28 17:31:52

回答

19

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[:] = v - 1 
+0

謝謝,這爲我清除了很多困惑。 – 2017-04-26 02:48:15

11

如果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),特別注意在-=左側使用的數組。

+1

+1即使這不是原因;我完全忽略了這種可能性,不應該有。 – DSM 2012-01-28 17:17:30

4

+1到兩個其他回答這個問題。他們涵蓋了=-=之間的兩個重要差異,但我想強調一個。大部分時間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.] 
+0

這太令人難以置信了。你能解釋第一個結果是如何產生的嗎? – 2017-04-26 02:50:49