配列の代入とコピー

目的

numpyモジュールのndarrayオブジェクトはミュータブルなオブジェクトである.ミュータブルなオブジェクトでは,代入文やコピーの扱いに注意する必要がある.ここでは,ndarrayオブジェクトの代入文とコピーについて学ぶ.

説明

同じ配列オブジェクトに別名をつける代入文

配列に別名をつける

配列に対して代入文を使用した以下の例を見てみよう.

5行目でoriginal_arrayという名前のオブジェクトを作り,6行目でoriginal_arrayをassigned_arrayに代入している.9行目でoriginal_arrayの0番目の要素に値9を代入している.

このプログラムを実行すると,以下のようになり,original_arrayの0番目の要素とassigned_arrayの0番目の要素が9に変わっていることがわかる.このことから,6行目のような代入文では,同じ配列オブジェクトに別名をつけており,両者は同じオブジェクトを指していることがわかる.

配列をスライスして別名をつける

では,スライスにより配列の一部を取り出して代入する以下の例を見てみよう.

5行目でoriginal_arrayという名前の配列オブジェクトを作り,6行目でその一部を取り出し,sliced_arrayに代入している.9行目でsliced_arrayの0番目の要素に値9を代入している.

このプログラムを実行すると,以下のようになり,sliced_arrayの0番目の要素とoriginal_arrayの2番目の要素が9に変わっていることがわかる.このことから,6行目のように代入する場合も,同じオブジェクトの一部に名前をつけていることになっており,どちらかの名前で参照した要素の値を更新すると,もう片方の要素の値も書き換えられることがわかる.

配列オブジェクトをコピーして名前をつける代入文

配列をコピーする

次に,配列オブジェクトをコピーする例を見てみよう.

6行目のように配列オブジェクトのcopyメソッドを呼び出して代入している.9行目のようにoriginal_arrayの0番目の要素を変更すると,以下の実行結果からわかるように,original_arrayの0番目の要素だけが書き換えられている.このことから,6行目のように記述すると,配列オブジェクトがコピーされていることがわかる.

配列をスライスしてコピーする

スライスにより配列の一部を取り出してコピーする例も見てみよう.

6行目のようにスライスにより配列の一部を取り出し,copyメソッドを呼び出して代入している.9行目でスライスにより取り出した配列の0番目の要素を変更すると,以下の実行結果からわかるように,スライスにより取り出した配列の0番目の要素だけが書き換えられている.このことから,6行目のように記述すると,配列オブジェクトの一部がコピーされていることがわかる.

新しく配列オブジェクトを生成して名前をつける代入文

以下のような3つの代入文を見てみよう.

5行目でaという名前の配列オブジェクトを作り,7行目でaの内容を別の配列オブジェクトで入れ替え,9行目でaの要素に1を足すことで,値を更新しているようにも見れる.6,8,10行目で配列オブジェクトaのid番号を表示すると,以下のようになり,それぞれのオブジェクトの実体が異なることがわかる.このことから,5,7,9行目のような代入文では,新しく配列オブジェクトが生成され,それに名前をつけていることが確認できる.

先程の9行目の処理は以下の7行目のように書くこともできる.

このプログラムの実行結果は以下のようになり,7行目の処理では新しいオブジェクトが生成されていないことがわかる.「a = a + 1」と「a += 1」は両者ともの配列aの各要素に1を加算する処理を表しているが,前者では新しいオブジェクトが生成され,後者では同じオブジェクトの要素の値が変更されるという違いがある.

課題

課題0

配列オブジェクトを生成し,そのオブジェクトに別名をつけ,元の配列の要素を変更せよ.

課題1

配列オブジェクトを生成し,そのオブジェクトの一部をスライスして別名をつけ,スライスした配列の要素を変更せよ.

課題2

配列オブジェクトを生成し,そのオブジェクトをコピーし,元の配列の要素を変更せよ.

課題3

配列オブジェクトを生成し,そのオブジェクトの一部をスライスしてをコピーし,スライスした配列の要素を変更せよ.

課題4

10個の要素をもつ配列を生成し,2通りの方法で配列の要素の値に1を加算し,新しいオブジェクトが生成されたか,元のオブジェクトの要素の値が更新されたかを確認せよ.