Hello Computer Vision

파이썬 copy, deepcopy 쓰는 이유 및 사용해보기 본문

딥러닝/파이썬

파이썬 copy, deepcopy 쓰는 이유 및 사용해보기

지웅쓰 2024. 1. 17. 22:36

모델을 훈련 전에 복사할 필요성이 생겼는데 이번 기회에 copy,  deepcopy를 비교해보려고 한다.

 

1. 다른 변수로 할당

우선 코딩 초보인 나에게 해당 변수 값을 다른 변수에 넘겨주면은 되지 않나 생각을 했다.

a = [1,2,3]
b = a
a.append(4)
print(f'a: {a}, 주소 : {id(a)}')
print(f'b: {b}, 주소 : {id(b)}')
a: [1, 2, 3, 4], 주소 : 2603786361344
b: [1, 2, 3, 4], 주소 : 2603786361344

이렇게 다른 변수를 사용하더라도 기존 변수에 대한 참조를 하기 때문에 값이 같이 변하는 것을 확인할 수 있고 메모리 주소도 같은 것을 확인할 수 있다. 이렇게 새로운 변수 생성하는 방법을 왜 사용하는지에 대해 생각해봤는데 기존의 가지고 있던 값을 일시적으로 저장하기 위해 사용했던 거 같다.

 

2. copy

a = [1,2,3]
b = a.copy()

a.append(4)

print(f'a: {a}, 주소 : {id(a)}')
print(f'b: {b}, 주소 : {id(b)}')
a: [1, 2, 3, 4], 주소 : 2965465058048
b: [1, 2, 3], 주소 : 2965464985152

우선 파이썬 내장메소드인 copy를 사용해서 복사를 해보면 위에서 한 것과는 달리 주소가 다른 것을 확인할 수 있다. 그러나 이렇게 차원을 늘린다면 어떻게 될까?

a = [[1,2], [3,4]]
b = a.copy()
a[1][1] = 5
print(f'a: {a}, 주소 : {id(a)}')
print(f'b: {b}, 주소 : {id(b)}')
print(f'a[1]: {a[1]}, 주소 : {id(a[1])}')
print(f'b[1]: {b[1]}, 주소 : {id(b[1])}')
a: [[1, 2], [3, 5]], 주소 : 2406116040832
b: [[1, 2], [3, 5]], 주소 : 2406116084800
a[1]: [3, 5], 주소 : 2406116024512
b[1]: [3, 5], 주소 : 2406116024512

이렇게 리스트 전체의 주소는 다르지만 2차원 리스트의 경우 a의 주소를 b가 참조하는 것을 확인할 수 있다. 이런 것을 shallow copy라고 한다. 즉, 이미지를 다룰 때는 높은 차원의 텐서를 다룰 때가 많으므로 copy는 사용하지 않는 것이 좋다.

 

3. deepcopy

내장 모듈인 deepcopy를 사용해보면 어떨까

import copy
a = [[1,2], [3,4]]
b = copy.deepcopy(a)
a[1][1] = 5
print(f'a: {a}, 주소 : {id(a)}')
print(f'b: {b}, 주소 : {id(b)}')
print(f'a[1]: {a[1]}, 주소 : {id(a[1])}')
print(f'b[1]: {b[1]}, 주소 : {id(b[1])}')
a: [[1, 2], [3, 5]], 주소 : 1667788972288
b: [[1, 2], [3, 4]], 주소 : 1667789016320
a[1]: [3, 5], 주소 : 1667788955968
b[1]: [3, 4], 주소 : 1667753870784

모든 데이터가 서로 다른 주소를 가지고 있음을 알 수 있다.