pythonの標準配列は,=で複製できる.
ただし,これは参照渡しであるため,元の配列を変更するとコピーした配列も変更されてしまう.
.py
>>> a = [1,2]
>>> b = a
>>> b
[1, 2]
>>> a[0] = 999
>>> a
[999, 2]
>>> b
[999, 2]
これは,以下のような場合においても同様である.
.py
>>> a = [[1,2],[3,4]]
>>> b = a
>>> b
[[1, 2], [3, 4]]
>>> a[0][0] = 999
>>> a
[[999, 2], [3, 4]]
>>> b
[[999, 2], [3, 4]]
.py
>>> a = [1,2]
>>> b = [3,4]
>>> c = [a,b]
>>> c
[[1, 2], [3, 4]]
>>> a[0]=999
>>> a
[999, 2]
>>> c
[[999, 2], [3, 4]]
これを防ぐには,ライブラリcopy.copyまたはcopy.deepcopyを使う.この際,copyをimportする必要がある.
copyは対象オブジェクトのみをコピーする.deepcopyはオブジェクト内のオブジェクトもコピーしてくれる.よって,1次元配列ではcopyで十分であるが,2次元配列の複製にはdeepcopyを用いる.
.py
>>> import copy
>>> a = [1,2]
>>> b = copy.copy(a)
>>> b
[1, 2]
>>> a[0] = 999
>>> a
[999, 2]
>>> b
[1, 2]
.py
>>> import copy
>>> # copyを使った場合
>>> a = [[1,2],[3,4]]
>>> b = copy.copy(a)
>>> b
[[1, 2], [3, 4]]
>>> a[0][0] = 999
>>> a
[[999, 2], [3, 4]]
>>> b
[[999, 2], [3, 4]]
>>> # deepcopyを使った場合
>>> a = [[1,2],[3,4]]
>>> b = copy.deepcopy(a)
>>> b
[[1, 2], [3, 4]]
>>> a[0][0] = 999
>>> a
[[999, 2], [3, 4]]
>>> b
[[1, 2], [3, 4]]
これはnumpyでも同様である.ただし,numpyの場合は2次元配列でもcopyで別の配列として複製できる.2次元配列自体が1つのnumpyのオブジェクトとなっているため?
.py
>>> import numpy as np
>>> import copy
>>> # copyなし
>>> a = np.array(([[1,2],[3,4]]))
>>> b = a
>>> b
array([[1, 2],
[3, 4]])
>>> a[0,0] = 999
>>> a
array([[999, 2],
[ 3, 4]])
>>> b
array([[999, 2],
[ 3, 4]])
>>> # copy(もちろんdeepcopyでもよい)
>>> a = np.array(([[1,2],[3,4]]))
>>> b = copy.copy(a)
>>> b
array([[1, 2],
[3, 4]])
>>> a[0,0] = 999
>>> a
array([[999, 2],
[ 3, 4]])
>>> b
array([[1, 2],
[3, 4]])
numpy配列の結合にはr_またはc_を使用することができるが,このときコピー先配列はコピー元とは独立した配列となる.以下のコードを参照.
.py
>>> a = np.array(([[1,2]]))
>>> b = np.array(([[3,4]]))
>>> c = np.r_[a,b]
>>> c
array([[1, 2],
[3, 4]])
>>> a[0,0] = 999
>>> a
array([[999, 2]])
>>> c
array([[1, 2],
[3, 4]])
numpyの配列の単一行をcopyし,その部分をdeleteしてもコピー先の配列には影響しない.
.py
>>> a = np.array(([[1,2],[3,4]]))
>>> b = a[0,:]
>>> b
array([1, 2])
>>> a = np.delete(a,0,0)
>>> a
array([[3, 4]])
>>> b
array([1, 2])
>>> a[0,0] = 999
>>> a
array([[999, 4]])
>>> b
array([1, 2])