배열에는 복사(copy)와 뷰(view)라는 기능이 존재한다. 복사는 기존 배열을 복사하여 새로운 배열을 생성하는 개념이고, 뷰는 단지 기존에 있던 배열을 보여준다는 개념이다. 복사와 기존 배열은 상호간에 간섭을 하지 않는다. 하지만 뷰는 기존 배열과 어느 것이든 변화를 준다면 상호적으로 영향을 끼친다. 복사와 뷰를 활용하여 numpy에서 shape, reshape를 알아보자.
배열의 모양
복사(copy)
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
x = arr.copy()
arr[0] = 42
print(arr)
print(x)
위 코드는 복사의 예제 인데 x가 arr의 배열을 copy() 메소드를 통해 복사하였다. 그리고나서 x의 0번째 인덱스를 42로 채우고 arr과 x를 각각 출력한다.
[42 2 3 4 5]
[1 2 3 4 5]
copy는 앞서 말했듯 기존 배열과 상호 간섭을 하지 않는다. 따라서 바꾼 기존 배열의 0번째 인덱스만 바뀌고 복사된 x 배열은 복사했던 때의 배열 그대로 존재한다.
뷰(view)
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
x = arr.view()
x[0] = 31
print(arr)
print(x)
위 코드는 x에 arr의 배열을 view() 메소드로 뷰화 시켰는데 x의 0번째 인덱스에 변화를 주었다. 따라서 기존 배열인 arr의 0번째 인덱스 변화 한 것을 볼 수 있다.
[31 2 3 4 5]
[31 2 3 4 5]
복사와 뷰의 기원 배열
만약 복사된 배열과 뷰화 된 배열을 구분을 하고싶다면 base 메소드를 사용하면 된다. 만약 view 메소드가 사용되었다면 기존 배열이 출력될 것이고 copy 메소드를 사용했다면 copy는 새로 생성된 배열이기 때문에 None이 출력된다.
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
x = arr.copy()
y = arr.view()
print(x.base)
print(y.base)
#결과
None
[1 2 3 4 5]
배열 모양(shape) 가져오기
배열의 모양은 각 차원의 요소를 알려준다. 배열의 shape를 사용해보자.
import numpy as np
arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
print(arr.shape)
위 코드는 2차원 배열을 선언하고 shape를 사용하여 배열의 각 차원의 요소 수를 출력한다. 실행하면 ‘(2, 4)’로 출력되는데 겉에서부터 수를 센다. 먼저 첫번째 차원 배열이 2개 이므로 2, 두번째 차원 배열에는 각각 4개씩 있으므로 4가 출력된다. 만약 두 요소의 개수가 일치하지 않으면 오류가 발생한다. 배열이 두 개의 행과 4개의 열이라 생각하니 이해하기 쉬웠다.
만약 차원의 수를 미리 정하면 shape의 출력 결과는 어떻게 될까? 아래 예제를 보자.
import numpy as np
arr = np.array([1, 2, 3, 4], ndmin=5)
print(arr)
print('shape of array :', arr.shape)
#결과
[[[[[1 2 3 4]]]]]
shape of array : (1, 1, 1, 1, 4)
당연하게도 맨 안쪽 차원에 배열이 새워지기 때문에 마지막 차원만 4, 나머지는 1이 된다.
배열의 모양변경(reshaping)
모양변경된 배열
Reshaping이란 배열의 모양을 변경하는 것을 의미한다. 모양변경을 통해서 각 차원의 요소 수를 관리 할 수 있고, 각 차원도 관리 할 수 있다. 예제를 보자.
1차원에서 2차원으로 만들기
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
newarr = arr.reshape(4, 3)
print(newarr)
reshape의 인자는 배열안의 요소 수를 인자로 받는다. 위 코드에서 reshape(4,3)은 12개의 요소를 가지던 배열을 2차원은 4개, 1차원은 3개로 요소를 준다는 말이다.
#결과
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
1차원에서 3차원으로 만들기
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
newarr = arr.reshape(2, 3, 2)
print(newarr)
위 코드도 똑같이 동작한다.
#결과
[[[ 1 2]
[ 3 4]
[ 5 6]]
[[ 7 8]
[ 9 10]
[11 12]]]
모양변경의 제약
그러면 만약 기존에 있던 요소 수와 우리가 요구하는 요소 수가 다르면 어떻게 될까 ?
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
newarr = arr.reshape(3, 3)
print(newarr)
위 코드 같이 기존 배열의 요소 수가 8개, 변경 될 배열은 2차원 배열 3개 1차원 배열 3개로 총 9개가 필요하므로 오류가 발생하게 된다.
Reshape된 배열 복사본, 뷰 체크하기
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
print(arr.reshape(2, 4).base)
위 코드처럼 base 메소드를 reshape 메소드로 반환된 결과에도 사용가능하다. reshape는 기존 구조를 변경하는 것이기 때문에 뷰에 속하여 결과가 기존 배열과 똑같이 나온다.
알려지지 않은 차원
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
newarr = arr.reshape(2, 2, -1)
print(newarr)
하나의 차원에 대해 “알 수 없는” 차원을 설정할 수 있다. 이 경우 -1을 사용하면 NumPy가 나머지 차원을 자동으로 계산한다.
#결과
[[[1 2]
[3 4]]
[[5 6]
[7 8]]]
배열 평탄화
다차원 배열을 1차원 배열로 변환하는 것을 평탄화(Flattening)라고 한다. 이를 위해 reshape(-1)을 사용할 수 있다.
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
newarr = arr.reshape(-1)
print(newarr)
#결과
[1 2 3 4 5 6]
참고 – w3schools
최신글
![[프로그래머스] 잘라서 배열로 저장하기 - 자바](https://develog.co.kr/wp-content/uploads/2025/01/프로그래머스-잘라서-배열로-저장하기-자바-150x150.png)
![[프로그래머스] 붕대 감기 - 자바](https://develog.co.kr/wp-content/uploads/2024/11/프로그래머스-붕대-감기-자바-150x150.png)
![[프로그래머스] 달리기 경주 - 자바](https://develog.co.kr/wp-content/uploads/2024/11/프로그래머스-달리기-경주-자바-150x150.png)