0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Python,numpyの配列のコピー周りの挙動備忘録

Posted at

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])
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?