5.5. ビューとコピー#
配列の実態にはビュー(view) とコピー(copy)の 2 種類があります。配列を生成したあと、その配列の一部を取り出した部分配列や、np.ravel
などの関数で形状を変えた配列は、見かけ上形は異なりますが、データを格納しているメモリを共有しています。このような配列を元の配列のビューと呼びます。
メモリを共有しているため、ビューの値を変更すると、元の配列の値も変更されます。
x = np.array([[1, 2, 3, 4],
[5, 6, 7, 8]])
a = np.ravel(x)
a[0:4] = 0
x
array([[0, 0, 0, 0],
[5, 6, 7, 8]])
逆に、元の配列 x
の要素を変更すると、その変更はビュー a
にも反映されます。
x[1, :] = -1
a
array([ 0, 0, 0, 0, -1, -1, -1, -1])
このように、ビューは同じデータを共有しているため、片方を変更するともう片方にも影響が出ます。
一方、コピーは元の配列とは独立した別の配列です。コピーを作成するには、配列の copy
メソッドを使います。例えば、先ほどの np.ravel
で作成したビューに対して .copy()
を呼び出すと、コピーが作成されます。コピーに対して値を変更しても、元の配列のデータは変更されません。
x = np.array([[1, 2, 3, 4],
[5, 6, 7, 8]])
a = np.ravel(x)
b = a.copy()
b[0:4] = 0
x
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
x[1, :] = -1
b
array([0, 0, 0, 0, 5, 6, 7, 8])
また、次のように、配列の構造を変換した直後に copy
をつけて、1 行で済ますこともできます。
x = np.array([[1, 2, 3, 4],
[5, 6, 7, 8]])
a = np.ravel(x).copy()
a
array([1, 2, 3, 4, 5, 6, 7, 8])
コピーしたつもりがビューだった。気づかず喜んでたら、卒業要件ひとつ消えてた。ビューの取り扱い、人生より慎重に。