4

コード内のコピーの量を減らそうとしているのですが、以下で説明されているように、numpy 配列のスライスとビューを処理するときに驚くべき動作に遭遇しました。

numpy 配列のコピーに関する Scipy wiki ページ

次の動作に出くわしましたが、これは私にとって予期しないものです。

ケース 1.:

import numpy as np
a = np.ones((3,3))
b = a[:,1:2]
b += 5
print a
print b.base is a

予想どおり、これは次のように出力されます。

array([[ 1.,  6.,  1.],
       [ 1.,  6.,  1.],
       [ 1.,  6.,  1.]])
True

ケース 2:スライスと追加を 1 行で実行すると、見た目が異なります。

import numpy as np
a = np.ones((3,3))
b = a[:,1:2] + 5
print a
print b.base is a

私にとって驚くべき部分は、 a[:,1:2] がビューを作成していないように見えることです。ビューは左側の引数として使用されるため、次のように出力されます。

array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])
False

たぶん、誰かがこれら2つのケースが異なる理由を明らかにすることができます.私は何かが欠けていると思います.

解決策:インプレース演算子「+ =」以外の「+」演算子は常にコピーを作成するという明らかな事実を見逃していたため、実際には関連していませんが、numpy に対してインプレース演算子が定義されている方法以外はスライスされています配列。

これを説明するために、以下はケース 2 と同じ出力を生成します。

import numpy as np
a = np.ones((3,3))
b = a[:,1:2]
b = b + 5
print a
print b.base is a
4

3 に答える 3

2

a[:, 1:2]ビューを作成しますが、2 番目の例ではビューを変更しません。代わりに、+その引数から新しい配列を作成します。あなたがすることを仮定します

a = np.ones((3, 3))
b = a + 5

その場合、aこれはインプレースの追加ではないため、 への変更は期待できません。演算子は+ではなく です+=。2番目の例と同じです。

b = a[:, 1:2] + 5

a[:, 1:2]これはインプレース追加ではないため、 は変更されません。

于 2013-08-09T21:52:35.250 に答える