0

複製された配列のいくつかの値を変更しようとすると、元の配列も不思議なことに影響を受けます。

import numpy as np

x = np.zeros((3, 10))
y = x

print(x)
print(y, "\n")

y[1:3, 4:8] = 1

print(x)
print(y)

私のシステムの出力は次のとおりです。

[[ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]
 [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]
 [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]]
[[ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]
 [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]
 [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]]

[[ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]
 [ 0.  0.  0.  0.  1.  1.  1.  1.  0.  0.]
 [ 0.  0.  0.  0.  1.  1.  1.  1.  0.  0.]]
[[ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]
 [ 0.  0.  0.  0.  1.  1.  1.  1.  0.  0.]
 [ 0.  0.  0.  0.  1.  1.  1.  1.  0.  0.]]

現在、NumPy 1.6.2 を、 Python 3.2.3 と共にIntel MKL ( Christoph Gohlkeによる) に対してコンパイルされた 64 ビット バージョンとして使用しています。32ビットの「公式」バージョンも試しましたが、まったく同じ結果が得られました...

4

1 に答える 1

1

アレイのコピーを作成していません。同じ配列への新しい参照を作成しただけです。配列をコピーする場合は、次を使用しますnumpy.copy

y = numpy.copy(x)

通常の python リストでは、構文the_list[:]([:]元のリストの最初から始まり最後で終わるスライスを作成することを意味します) を使用して浅いコピーを取得できますが、ほとんどの場合、numpyスライスは実際にはビューです。

>>> import numpy as np
a>>> a = np.arange(10)
>>> b = a[:]
>>> b[0] = 100
>>> a
array([100, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> b
array([100, 1, 2, 3, 4, 5, 6, 7, 8, 9])

対:

>>> a = range(10)
>>> b = a[:]    # does a real copy
>>> b[0] = 100
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> b
[100, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Python では、すべての識別子はオブジェクトへの参照です。課題を行う場合:

y = x

割り当ては、によって参照されるオブジェクトに名前をバインドします。つまり、 の参照のコピーになります。によって参照されたオブジェクトには、もう 1 つの参照があります。オブジェクトに参照がなくなると、メモリから削除されます。Python には、C に見られるような「変数」の概念がありません。yxyxx

別の考え方として、任意の識別子はオブジェクトへのポインターであるというものがあります。したがって、オブジェクト自体ではなくポインターy = xをコピーします(これが実際に起こることです。C/API は常に構造体へのポインターを使用します) 。PyObject

numpyこれは、すべての python チュートリアルで説明されているため、少し脇に置き、最初に python チュートリアルを読むことをお勧めします。


いくつかの Unicode アートを使用してバインドで何が起こるかを説明することにしました。このアイデアは私のものではなく、python-it.org フォーラムのユーザー Claudio_F のものです。

Python には識別子があり、これをブイとして表します。各ブイは、海の下の岩 (または何でも) として表されるオブジェクトに接続できます。オブジェクトは、より多くのブイにバインドできます。オブジェクトがブイに拘束されていない場合、海に沈み、海底に到達すると、巨大な海の怪物 (ガベージ コレクターとも呼ばれます) によってオブジェクトが破壊されます。

割り当てを行うと、次のようになります。

a = 5

これは状況です:

             ___
            (   )
            ( a )
            (   )
^~~~~^~~~~^~~'¿'~~~~^~~~~~^~~~~~^~~~~~~
              |
  O        .--+--.         o    ___
           |  5  |           |\/  x\
           .-----.            ^\_/


             ___             O
    o       /o  \/|
            〉 GC  |       o      o
            \___/\|
        (   
   )     )             (
  (     (      )        )        )
(  )  )  )    (   (    ( (    ) ( (
 )(  (  (   (  )   )    ) )  (   ) )

割り当てを行う場合:

b = a

両方のブイが同じオブジェクトにバインドされています。

            ___               ___
           (   )             (   )
           ( a )             ( b )
           (   )             (   )
^~~~^~~~~^~~'¿'~~~~~^~~~~^~~~~'¿'~~~~^~~~~~^
             \        o       /
              \     o        /
               \     O      /
                \          /    __________
                 \        /    /          \
       o          \      /    /            \
                   \    /       )  | (  | )
     O              \  /       (   |  )  (
        o            \/            | (    )
                  .--+--.             )
                  |  5  |
                  .-----.



             ___             O
    o       /o  \/|
            〉 GC  |       o      o
            \___/\|
        (   
   )     )             (
  (     (      )        )        )
(  )  )  )    (   (    ( (    ) ( (
 )(  (  (   (  )   )    ) )  (   ) )

3 番目の割り当てを行う場合:

a = 7

aチェーンはオブジェクトから解き放たれ、5新しいオブジェクトにバインドされ7ますが、bブイはオブジェクトにバインドされたまま5です:

            ___               ___
           (   )             (   )
           ( a )             ( b )
           (   )             (   )
^~~~^~~~~^~~'¿'~~~~~^~~~~^~~~~'¿'~~~~^~~~~~^
             |         o       |
             |                 |
             |     O           |      o
             |                 |
     o       |                 |
             |        o        |
             |              .--+--.
   O      .--+--.           |  5  |
          |  7  |           .-----.
          .-----.

     o     



             ___             O
    o       /o  \/|
            〉 GC  |       o      o
            \___/\|
        (   
   )     )             (
  (     (      )        )        )
(  )  )  )    (   (    ( (    ) ( (
 )(  (  (   (  )   )    ) )  (   ) )

写真を楽しんでいただき、それがどのように機能するかを明確にしていただければ幸いです. (クラゲも死んだ魚もカッコイイと思ったから)

ちなみに、この表現はオブジェクト間の参照を理解するのにも最適です。たとえば、コード:

L = [1,2,3]

次のように表されます。

                ___
               (   )
               ( L )
               (   )
 ^~~~~^~~~~^~~~~'¿'~~~~^~~~~^~~~~^~~~~^
                 |
                 |
        .--------+----------.
        | [ '¿', '¿', '¿' ] |
        .----|----|----|----.
            /     |     \
           /      |      \
       .--+--.    |    .--+--.
       |  1  |    |    |  3  |
       .-----.    |    .-----.
                  |
               .--+--.
               |  2  |
               .-----.



             ___             O
    o       /o  \/|
            〉 GC  |       o      o
            \___/\|
        (   
   )     )             (
  (     (      )        )        )
(  )  )  )    (   (    ( (    ) ( (
 )(  (  (   (  )   )    ) )  (   ) )

リストには、実際のオブジェクトではなく、オブジェクトへの「ポインター」があることに注意してください。

また、スライスに戻ると、次のようになります。

R = L[:]

次のシナリオが得られます。

                ___                        ___
               (   )                      (   )
               ( L )                      ( R )
               (   )                      (   )
 ^~~~~^~~~~^~~~~'¿'~~~~^~~~~^~~~~^~~~~^~~~~'¿'~~~~~~^~~~~~^~~~~~
                 |                          |
                 |                          |
        .--------+----------.     .---------+---------.
        | [ '¿', '¿', '¿' ] |     | [ '¿', '¿', '¿' ] |
        .----|----|----|----.     .----|----|----|----.
             \     \    \             /    /    /
              \     \    \           /    /    /
               \     \    \         /    /    /
                \     \    \       /    /    /
                 \     \    \     /    /    /
                  \     \    \   /    /    /
                   \     \    \ /    /    /
                    \     | .--+--. |    /
                     \    | |  1  | |   /
                      \   | .-----. |  /
                       \   \       /  /
                        \   \     /  /
                         \   \   /  /
                          |   \ /   |
                          | .--+--. |
                          | |  2  | |
                          | .-----. |
                           \       /
                            \     /
                             \   /
                              \ /
                            .--+--.
                            |  3  |
                            .-----.



             ___             O
    o       /o  \/|
            〉 GC  |       o      o
            \___/\|
        (                                (
   )     )             (                  )   (     
  (     (      )        )        )       (  )  )     )        (
(  )  )  )    (   (    ( (    ) ( (    )  )(  (  (  (          )(
 )(  (  (   (  )   )    ) )  (   ) )  (  (  )  )  )  )      ) (  )

両方のリストが同じオブジェクトを指していることに注意してください。それが浅いコピーと呼ばれる理由です。整数の代わりに、他のリストのように変更可能なオブジェクトを配置すると、それを変更すると両方のリストの内容が変更される理由が明確に理解できます。

于 2013-02-05T12:37:42.523 に答える