2016-11-05 12 views
0

コードnumpyの組み込みコピーリストVS

以下差内蔵リストコード

>>> a = [1,2,3,4] 
>>> b = a[1:3] 
>>> b[1] = 0 
>>> a 
[1, 2, 3, 4] 
>>> b 
[2, 0] 

numpyのアレイ

>>> c = numpy.array([1,2,3,4]) 
>>> d = c[1:3] 
>>> d[1] = 0 
>>> c 
array([1, 2, 0, 4]) 
>>> d 
array([2, 0]) 

としては何かそれはnumpy arrで見られるay cは直接影響を受ける。私は組み込みのリストでは、新しいメモリが変数bに割り当てられていると思います。おそらくnumpyではc [1:3]の参照にdが割り当てられていますが、私はこれらについてはっきりしていません。 これはnumpyと組み込みでどのように機能しますか?

+0

[リスト対ベクトル対配列]の可能な重複(http://stackoverflow.com/questions/1905417/array-vs -vector-vs-list) – polka

+0

@polkaは素早く答えてくれてありがとうございます。 – umtkas

+0

numpyのリストを話すのは正しくないことに注意してください。これは配列の数が少ないです。 – chthonicdaemon

答えて

2

重要なポイントは、Pythonのすべての割り当てがメモリ内のオブジェクトに名前を関連付けることです。 Pythonは割り当てをコピーしません。新しいオブジェクトがいつ作成され、どのように動作するかを理解することが重要になります。

最初の例では、リストのスライスによって新しいリストオブジェクトが作成されます。この場合、両方のリストは同じオブジェクトの一部を参照します(int 2およびint 3)。これらの参照がコピーされるということは、「浅い」コピーと呼ばれます。つまり、参照はコピーされますが、参照先のオブジェクトは同じです。リストに格納されているものの種類にかかわらず、これは正しいことに注意してください。

ここで、新しいオブジェクト(int 0)を作成し、b[1] = 0を割り当てます。 abは別々のリストなので、異なる要素を表示していることを驚かせてはいけません。

私はこの状況のpythontutor visualisationが好きです。

アレイの場合、"All arrays generated by basic slicing are always views of the original array."です。

この新しいオブジェクトは元のデータとデータを共有し、インデックスの割り当ては、ビューの更新によって共有データが更新されるように処理されます。

2

これは多く説明されていますが、優れた複製を見つけることはあまりにも多くの作業です。 :(

は、私はすぐにあなたの例で物事を記述することができるかどうか見てみましょう:

>>> a = [1,2,3,4] # a list contains pointers to numbers elsewhere 
>>> b = a[1:3] # a new list, with copies of those pointers 
>>> b[1] = 0 # change one pointer in b 
>>> a 
[1, 2, 3, 4] # does not change any pointers in a 
>>> b 
[2, 0] 

arrayは異なる構造を持っている - それは「生の」番号(または他のバイト値)とのデータバッファを持ってい

。 。リストを持つ
numpy array 
>>> c = numpy.array([1,2,3,4]) 
>>> d = c[1:3]  # a view; a new array but uses same data buffer 
>>> d[1] = 0  # change a value in d; 
>>> c 
array([1, 2, 0, 4]) # we see the change in the corrsponding slot of c 
>>> d 
array([2, 0]) 

キーポイントは、あなたがオブジェクトをコピーせずにポインタをコピーすることができ、彼らはオブジェクトへのポインタを含んでいることであり、あなたはポインタの他のコピーを変更することなく、ポインタを変更することができます

0123。

メモリを節約し、numpyを実行すると、viewのコンセプトが実装されました。データバッファを共有できるため、元の値をコピーせずに新しい配列を作成することができます。しかし、例えばコピーを作成することも可能である。

e = c[1:3].copy() 
e[0] = 10 
# no change in c 

view V copyは、インデックスの種類(スライス、基本的な、高度)を扱う場合は特に、numpyで大きな話題と基本的なものです。私たちは質問をすることができますが、numpyのドキュメントも読んでください。 numpy配列がどのように格納されているかの基礎を理解するための代替手段はありません。

http://scipy-cookbook.readthedocs.io/items/ViewsVsCopies.html

http://www.scipy-lectures.org/advanced/advanced_numpy/(あなたが今必要なものがより高度な可能性がある)

関連する問題