2012-01-28 15 views
12

私はPythonコードで--=に関連するいくつかの奇妙な動作をしています。私はnumpyのを使ってQR分解を書き込み、ダブルループ内のコードの次の行を持っています:qrは両方numpy.arrayあり、そしてvv = x[:,j]として取られ、他のnumpy.arrayのスライスです- vs - = numpyの演算子

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

を。

上記のコードは、すべての場合に期待どおりに機能しません。しかし、私が次のように変更した場合:

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

すべてがうまく機能します。

私は、これらの2つの行が同一でなければならないという印象を受けました。 -=_ = _ -が異なっ働いていたかどうかをテストするために、私は再び両方のprint文で[2 3] [2 3]を生産、期待通りに動作します次のスニペット

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つのラインが異なる動作をするのか全くわかりません。私が考えることができる唯一の可能なことは、時々(10^-8以下のオーダーの)非常に小さい数字を取り扱っているということで、-=がより良いという精密な問題がありますか? xの要素が小さくなるにつれて、最初の行がますます悪化します。

このような問題について他の投稿がある場合はお詫び申し上げます。--=を検索することはできません。これらの割り当て/演算子以外の正しい用語があるかどうかわかりません。

ありがとうございました!

+4

あなたは 'のために、このようなものの名前を検索したい場合は-'と' - = 'ある[' __sub__'] [1]と[ '__isub__'] [2]それぞれ、したがって: 'a = a .__ sub __(b) 'と同等です。 ' a - = b'は 'a .__ isub __(b)'と同等です。 (__isub__が定義されていない場合は、上記に戻ります) [1]:http://pyref.infogami.com/__add__ [2]:http://pyref.infogami.com/__iadd__ –

答えて

19

vがスライスの場合、v -= Xv = v - Xは非常に異なる結果を生成します。 v -= 1は対、インプレース、したがって、それは見てのアレイをスライスを更新し、

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

を考えてみましょうそのままxを残しv = v - 1が可変vをリセット

>>> 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 
+0

ありがとう、これは私のために多くの混乱をクリアします。 –

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

4

+1を行う必要があるだろう。彼らは=-=の2つの重要な違いをカバーしていますが、もう一つ強調したいと思います。 x -= yの時間の大部分はx[:] = 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

それは信じられないほどうんざりです。最初の結果がどうなるか説明できますか? –