[1] Memory Optimization

- copy : 원본에 영향을 미치면 안될때
- view : 원본에 영향을 미쳐도 될때
- 넘파이의 slicing은 view를 만드는것이다. 그래서 원본에도 영향을 미친다
[2] base of ndarrays
- view인지 copy인지 구분하는 것이 바로 base이다
- 하지만 모든 경우를 커버하지는 못한다
- view를 통해 만들어진 객체들의 base는 바로 자기의 메모리 어드레스를 제공해주는 ndarray이다
- np.reshape은 view를 통해 새로운 객체를 만들어내었기 때문에 그 객체를 수정하는 순간 원본에도 영향을 미치게 된다.
- 반면에, np.resize는 copy를 통하여 새로운 객체를 생성한다
- reshape을 이용할때 원본에 영향을 미치지 않기 위해서는 reshape을 해주고 뒤에 .copy를 붙여준다
- raven -> view , flatten -> copy
- flatten -> 원소를 수정하겠다
- ravel -> 원소를 수정하지 않겠다
import numpy as np
#view
a = np.arange(5)
b = a.view()
b[0] = 100
print(a)
print(b)
#slicing
a = np.arange(5)
b = a[0:3]
b[...] = 10
print(a)
print(b)
#copy
a = np.arange(5)
b = a.copy()
b[0] = 100
print(a)
print(b)
# base of ndarrays
a = np.arange(5)
b = a.copy()
c = a.view()
d = a[0:3]
print(b.base is a) #False
print(c.base is a) #True
print(d.base is a) #True
#APIs and copy, view
#reshape
a = np.arange(4)
b = np.reshape(a,(2,2))
b[0,0] = 100
print(b.base is a, '\n')
print(a)
print(b)
#resize
a = np.arange(4)
b = np.resize(a,(2,2))
b[0,0] = 100
print(b.base is a, '\n')
print(a)
print(b)
#reshape.copy()
a = np.arange(4)
b = np.reshape(a, (2,2)).copy()
b[0,0] = 100
print(b.base is a, '\n')
print(a)
print(b)
#ravel -> view
a = randint(0, 10, (2,3))
b = a.ravel()
b[0] = -10
print(b.base is a, '\n')
print(a)
print(b)
#flatten -> copy
a = randint(0,10, (2,3))
b = a.flatten()
b[0] = -10
print(b.base is a, '\n')
print(a)
print(b)