a, b, c = np.arange(1682), np.arange(3804), np.arange(804)
a_2 = a.reshape((2, 841))
b_2 = a.reshape((2, 1902))
c_2 = a.reshape((2, 402))
print(a_2.shape, b_2.shape, c_2.shape)
오늘은 numpy 데이터를 좀 더 효과적으로 처리하는 방법에 대해 알아보겠다.
- reshape(-1)
굉장히 크거나 외부 데이터를 다루는 경우, 데이터 처리를 용이하게 하기위해 모양을 바꾸는 경우가 있다
예를 들어
a, b, c = np.arange(1682), np.arange(3804), np.arange(804)
print(a.shape, b.shape, c.shape) # (1682,) (3804,) (804,)
해당 데이터가 있다고 했을때, (2, x)의 모양으로 바꾸고 싶다면
기존에 알고 있는 방식으로 구현해보자면
a, b, c = np.arange(1682), np.arange(3804), np.arange(804)
a_2 = a.reshape((2, 841))
b_2 = b.reshape((2, 1902))
c_2 = c.reshape((2, 402))
print(a_2.shape, b_2.shape, c_2.shape) # (2, 841) (2, 1902) (2, 402)
위의 코드와 같이 하나하나 값을 넣어줘야할 것이다.
그런데, 외부 데이터의 경우 배열의 크기를 정확하게 알 수 없다면, 어떻게 해야할까?
그때 사용하는 것이 reshape(-1)이다.
a, b, c = np.arange(1682), np.arange(3804), np.arange(804)
a_2 = a.reshape((2, -1))
b_2 = b.reshape((2, -1))
c_2 = c.reshape((2, -1))
print(a_2.shape, b_2.shape, c_2.shape) # (2, 841) (2, 1902) (2, 402)
사용목적은 아니겠으나, 다양한 상황에서 배열의 크기에 따라 자동적으로 모양을 맞추어주는 기능을 수행한다
a = np.arange(16)
a_4_x = a.reshape((4,3)) # 앗! 오타, error
a_4_x = a.reshape((4,-1)) # 역시! 실수가 없네
print(a_4_x.shape) # (4, 4)
- flatten()
- flatten() 메소드를 한마디로 표현하면, "Vector로 만든다"이다.
- flatten는 영어로 "납작하게하다"이다.
a = np.arange(3*2*5).reshape((3,2,5))
print(a.shape,'\n',a)
# (3, 2, 5)
# [[[ 0 1 2 3 4]
# [ 5 6 7 8 9]]
# [[10 11 12 13 14]
# [15 16 17 18 19]]
# [[20 21 22 23 24]
# [25 26 27 28 29]]]
a_flat = a.flatten()
print(a_flat.shape,'\n',a_flat)
# (30,)
# [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
# 24 25 26 27 28 29]
- 다차원의 배열을 1차원 배열인 벡터로 변환시켜준다.
- 당연하겠지만, 변환은 a[0] a[1] a[2] 순으로 진행된다.
- copy()
- copy()는 copy라는 메소드명에서도 알 수 있듯이 복사하는 메소드이다.
- copy()와 비교 및 대조되는 메소드가 view()이다.
- view()를 먼저 살펴보면
a = np.arange(5)
b = a.view() # 기존의 Memory 사용
b[0] = 100
print(a) # [100 1 2 3 4]
print(b) # [100 1 2 3 4]
- view()가 기존 메모리 주소를 가져와 복사본을 만든다는 것을 보고, 나는 DB 개념 중 가상 테이블인 "View"가 생각났다. 다른 DB들은 어떤지 모르겠으나, Oracle의 경우 View라는 가상 테이블을 만들었을 때, 원본 테이블의 데이터가 바뀌면 View의 데이터 역시 바뀐다는 특징이 있다. (헷갈리지 말자고 적어봤다..)
- view()는 원본 데이터를 복사하는 메소드이지만, 원본 데이터의 주소를 복사한다!(원본과 같은 메모리 공유)
a = np.arange(5)
b = a[0:3] # view()와 동일
b[...] = 10
print(a) # [10 10 10 3 4]
print(b) # [10 10 10]
- view()와 같은 방식의 복사이다.
이후, copy()를 살펴보자
a = np.arange(5)
b = a.copy() # Memory 새로 할당
b[0] = 100
print(a) # [0 1 2 3 4]
print(b) # [100 1 2 3 4]
- view()와 달리 Memory를 새로 할당 받고, 원본의 주소가 아닌 원본의 값을 복사한다.
a = np.arange(5)
b = a.copy() # 새로운 Memory 할당
c = a.view() # 기존의 Memory 사용
d = a[0:3] # view()와 동일
print(a.base is None) # True
print(b.base is None) # True
print(b.base is a) # False
print(c.base is a) # True
print(d.base is a) # True
- ndarray.base는 "if memory is from some other object(메모리가 다른 개체의 메모리인지)"를 나타내는 속성이다.
- 위의 코드를 보면
a가 np.arange()를 통해 스스로 만들어졌듯,
b 역시 a.copy()를 통해 base없이 새로운 배열이 만들어졌다고 받아들여야 이해해야 할 것이다.
a = np.arange(4)
b = np.reshape(a, (2,2))
b[0,0] = 100
print(b.base is a, '\n') # True
print(a) # [100 1 2 3]
print(b) # [[100 1]
# [ 2 3]]
- 간단하게 살펴보면
x.reshape()는 모양은 바뀌지만, view()와 같이 기존의 Memory 주소를 복사하는 형식으로 데이터가 생성된다.
이를 해결하고 싶다면
a = np.arange(4)
b = np.reshape(a, (2,2)).copy()
b[0, 0] = 100
print(b.base is a, '\n') # False
print(a) # [0 1 2 3]
print(b) # [[100 1]
# [ 2 3]]
위의 코드와 같이, .reshape() 뒤에 .copy()를 붙여주는 것도 좋을 것이다.
- copy() 메소드는 데이터 처리시, 원본 데이터를 유지하고자 할때 사용하면 좋겠다.
* 참조
- https://numpy.org/doc/stable/reference/generated/numpy.ndarray.base.html
numpy.ndarray.base — NumPy v1.21 Manual
numpy.ndarray.base attribute ndarray.base Base object if memory is from some other object. Examples The base of an array that owns its memory is None: >>> x = np.array([1,2,3,4]) >>> x.base is None True Slicing creates a view, whose memory is shared with x
numpy.org
- ICT이노베이션 강의 신경식 강사님 강의자료
'머신러닝 > Numpy' 카테고리의 다른 글
[Numpy] #6 브로드캐스팅(Broadcasting) 심화 기초문법 공부하기 6 (0) | 2021.09.29 |
---|---|
[Numpy] #5 요소별 연산, 브로드캐스팅(Broadcasting) ndarray 가지고놀기 기초문법 공부하기 5 (0) | 2021.09.28 |
[Numpy] #3 무작위, 랜덤, 표본추출 (normal, random) 기초문법 공부하기 3 (0) | 2021.09.28 |
[Numpy] #2 ndarray의 속성 기초문법 공부하기 2 (0) | 2021.09.27 |
[Numpy] #1 넘파이란, 객체생성및처리 기초문법 공부하기 1 (0) | 2021.09.27 |
댓글