Numpy
- 수치계산을 하기 위한 파이썬 라이브러리
- 딥러닝에서 사용되는 텐서와 매우 유사
- 백테와 행렬 단위의 대용량 수치 연산을 빠르게 진행
- 병렬 연산한다.
백터(vector)
- 1차원 데이터(1차원 배열)
- 스칼라가 연속적으로 여러개 모여있는 것
- 스칼라(scalar): 단순하게 측정한 하나의 값
행렬(Matrix)
- 2차원 데이터(2차원 배열)
- 1차원 데이터가 여러개 모여 있는 것
벡터
import numpy as np
lst = [1,2,3,4,5,6]
arr = np.array(lst)
arr
=> array([1, 2, 3, 4, 5, 6])
행렬
lst = [
[1,2,3],
[4,5,6]
]
arr = np.array(lst)
arr
=> array([[1, 2, 3],
[4, 5, 6]])
- 3차원 배열
lst = [
[
[1,2,3],
[4,5,6]
],
[
[7,8,9],
[10,11,12]
]
]
arr = np.array(lst)
arr
=> array([[[ 1, 2, 3],
[ 4, 5, 6]],
[[ 7, 8, 9],
[10, 11, 12]]])
인덱싱과 슬라이싱
- 기본적으로 파이썬에서 사용되는 인덱싱과 슬라이싱을 그대로 따라간다.
자주쓰는 numpy 데이터 타입
- 데이터의 바이트 크기를 설정
np.array([1,2,3],dtype = np.int32) # 4 byte 크기의 정수
np.array([1,2,3],dtype=np.int64) # 8 byte 크기의 정수 (Default 값이라 출력이 안됨!)
np.array([1,2,3],dtype=np.uint8) # 1 byte 크기의 부호없는 정수(0~255) (이미지 처리할때 자주 쓰임)
=> array([1, 2, 3], dtype=int32)
=> array([1, 2, 3], dtype=int64)
=> array([1, 2, 3], dtype=uint8)
-----------------------------------------------------------------------------------------------
np.array([1,2,3],dtype=np.float32) # 4 byte 크기의 실수 (딥러닝 때 많이 사용)
np.array([1,2,3],dtype=np.float64) # 4 byte 크기의 실수 (Default 값이라 출력이 안됨!)
np.array([1,0,1],dtype=np.bool_) # numpy bool 타입!
=> array([1., 2., 3.], dtype=float32)
=> array([1., 2., 3.])
=> array([ True, False, True])
- 행과 열개수 파악
arr = np.array([
[1,2,3],
[4,5,6],
[7,8,9],
[10,11,12]
])
arr
arr.shape[0] # 행개수
arr.shape[1] # 열개수
=> 4
=> 3
- 다차원 슬라이싱
arr[:,1]
=> array([ 2, 5, 8, 11])
첫 번째 행을 전부 다 가져오고, 두번째 열은 1번 인덱스를 가져온다.
arr[:,::2]
=> array([[ 1, 3],
[ 4, 6],
[ 7, 9],
[10, 12]])
첫번째 행은 다 가져오고, 두번째 열에서 2를 step하여 인덱스값을 가져온다.
마스킹 (masking)
- bool 배열을 마스크로 사용하여 데이터의 특정 부분을 선택할 수 있다.
예시
array([[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9],
[10, 11, 12]])
mask_list = [True,False,True,False] # 행 선택
arr[mask_list]
=> array([[1, 2, 3],
[7, 8, 9]])
bool형식으로 list로 변수를 담아내고 출력하면 True행만 반환되는 것을 알 수 있다.
mask_list = [True,False,True] # 열 선택
arr[:,mask_list]
=> array([[ 1, 3],
[ 4, 6],
[ 7, 9],
[10, 12]])
다차원 슬라이싱을 이용하여 열만 출력할수도 있다.
- 여러개의 인덱스 값들을 이용해서 가져오기
index_list = [0,2] # 바깥 행에 0번째 행과 2번째열만 가져온다.
arr[index_list]
=>array([[1, 2, 3],
[7, 8, 9]])
바깥 행에 0번째 행과 2번열을 갖고 온다.
numpy 함수 알아보기
- 배열의 각 요소별로 연산(+,-,*/ 가능)
arr1 = np.array([1,5,1])
arr2 = np.array([3,2,7])
np.add(arr1,arr2) # arr1 + arr2
=> array([4, 7, 8])
- 브로드캐스팅 (Broadcasting)
- 배열의 모양이 다르더라도 어떠한 조건이 만족했을때 작은 배열을 자동으로 큰 배열 크기에 맞춘다.
np.array([
[1,2,3],
[4,5,6],
[7,8,9],
[10,11,12]
])
arr * np.array([1,2,3]) # 열의 크기를 맞춰주면 행이 늘어난다.
=> array([[ 1, 4, 9],
[ 4, 10, 18],
[ 7, 16, 27],
[10, 22, 36]])
다음과 같이 브로드 캐스팅을 이용하면 열의 크기(3)만 맞추면 행이 저절로 늘어나 곱해주는 것을 볼 수 있다.
- Norm
- 벡터의 크기를 측정하는 함수
- 다 더하고 절대값 씌운 것 = L1
- 제곱한 후 다 더하고 루트 씌운것 = L2
np.linalg.norm([-1,2,3],1) # L1 norm
np.linalg.norm([-1,2,3],2) # L2 norm (2는 디폴트라 입력안해도 된다!)
=> 6.0
=> 3.7416573867739413
- 내적(dot product)
- 두 벡터의 각 요소끼리 곱의 합
- 결과값은 스칼라가 나온다.
a = np.array([1,2,3])
b = np.array([4,5,6])
np.dot(a,b)
a @ b # 이렇게도 쓰인다!
=>32
- 행렬곱
- 2차원 공간에서 내적한다.
- 앞에 행렬의 열개수와 뒤에 행렬의 행개수가 동일해야한다.
- 연산결과는 shape는 앞에 행렬의 행개수와 뒤에 행렬의 열개수가 나온다.
x = np.array([
[80,90,70], # 한행은 한 학생의 과거 모의고사 점수
[81,93,72],
[71,73,62],
[61,70,72]
])
과거의 모의고사를 가지고, 가중치를 알면 미래 성적을 구할 수 있다.
w = np.array([ # 앞에 행렬의 열개수와 뒤에 행렬의 행개수가 동일
[0.4], # 가중치 를 구하면 예측이 가능!
[0.2],
[0.3]
])
x @ w # 다중회귀를 이용하여 미래를 예측할 수 있다.
다중회귀를 사용하여 미래 성적을 예측한다.
y = np.array([
[77], # 실제 시험에서의 점수
[80],
[71],
[65]
])
배열 만들기
- np.arrange
- range 함수와 비슷하지만 객체가 아닌 ndarray가 반환된다.
예시
np.arange(2,10,2)
=> array([2, 4, 6, 8])
- np.zeros
- 0으로 채워진 배열 만들기
np.zeros(10)
=> array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
---------------------------------------------------
np.zeros((2,3,4))
=> array([[[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]],
[[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]]])
- np.ones
- 1로 채워진 배열 만들기
np.ones((2,3,1))
=> array([[[1.],
[1.],
[1.]],
[[1.],
[1.],
[1.]]])
- np.full
- 지정한 값으로 채워진 배열을 만들 때
np.full([3,5],False)
=> array([[False, False, False, False, False],
[False, False, False, False, False],
[False, False, False, False, False]])
numpy 집계함수
최소값, 중앙값 등 최빈값을 제외한 다양한 집계함수를 사용할 수 있다.
scores = np.array([80,90,100,70,40,90]) # 다차원 가능
np.sum(scores), np.std(scores) # score.sum()
=> (470, 19.50783318453271)
- exp 함수: y=e^x
- 자연상수인 오일러의 수를 밑으로 하는 지수함수
- x 에 0이 들어가면 1, 1이 들어가면 오일러의 수가 나온다.
- x 값이 조금만 커져도 무한대로 빠진다.
- 그래서 스케일 조정을 해줘야된다.
np.exp([1,2,3]) # 기하급수적으로 커진다!
=> array([ 2.71828183, 7.3890561 , 20.08553692])
자연로그 함수: y=loge_x
- 오일러 수를 밑으로 하는 로그함수
- x에 0이하가 들어가면 무한대, 1이 들어가면 0
- 큰 수를 작게 만들어 정규분포에 가깝게 만듦
x가 0이하의 y의 값이 무한대에 가까워지는 것을 볼 수 있다.
즉, 데이터가 큰숫자를 처리할 때 자연로그 함수를 사용한다.
np.log(100000000000000)
=> 32.23619130191664
- 분위수
- 데이터를 크기 순서에 따른 위치값
- 이상치 영향을 덜 받는다.
- 0.5를 줄 경우 중앙값이 나온다.
arr = np.array([100,3,3,6,7,9,20,10,9])
np.quantile(arr,0.5), np.median(arr), np.mean(arr)
=> (9.0, 9.0, 18.555555555555557)
다음과 같이 분위수와 중앙값을 보면 평균에 비해 수가 작게 나오는 것을 알 수 있다.
이로써 분위수는 이상치에 영향을 덜 받는다.
- 정렬
np.sort(arr)
np.sort(arr)[::-1] # 내림차순
=> array([ 3, 3, 6, 7, 9, 9, 10, 20, 100])
=> array([100, 20, 10, 9, 9, 7, 6, 3, 3])
배열 조건연산
배열에서 조건연산은 True, False로 반환된다.
예시
scores = np.array([80,90,100,70,40,90])
scores >= 80 # masking 가능!
=> array([ True, True, True, False, False, True])
- np.any
- 조건에 참이 하나라도 있으면 True
np.any(scores >= 100)
=> True
- np.all
- 조건이 모두 참이면 True
np.all(scores >= 70)
=> False
-np.where
np.where(scores >= 80, 1, 0)
=> array([1, 1, 1, 0, 0, 1])
- np.clip
- 구조 = (array,min,max)
- 배열에 요소에 min보다 작으면 min으로 변경
- max보다 크면 max로 변경
- 이상치 제거하는 데 좋다.
array([[1, 2, 3],
[0, 0, 3],
[0, 5, 3]])
np.clip(arr,[1,3,1],[3,4,2])
=> array([[1, 3, 2],
[1, 3, 2],
[1, 4, 2]])
- 무한대값과 nan값(결측치)
np.inf와 np.nan
- 전처리 과정에서 nan, inf 값이 동시에 찾기
셀 수 있는 정상 수치를 찾는다.
np.isfinite(arr)
=> array([False, False, True, True, True, True])
- 무한대와 nan값을 0으로 초기화하기
arr[np.isfinite(arr) == False] = 0
arr
=> array([0. , 0. , 4. , 5. , 7. , 8.1])
numpy random
- rand 함수
- 0~1 사이에 랜덤값 반환
np.random.rand()
=> 출력할 때마다 값이 다름
배열도 가능하다.
np.random.rand(3,3,4)
=> array([[[0.20334628, 0.97235771, 0.3365398 , 0.57339741],
[0.98327426, 0.67012025, 0.2040247 , 0.59778891],
[0.30227852, 0.28058461, 0.95835101, 0.06884652]],
[[0.46307451, 0.25222799, 0.15999601, 0.28020491],
[0.06943581, 0.13306157, 0.57014365, 0.31451093],
[0.57866082, 0.61023913, 0.58615388, 0.53240497]],
[[0.41231987, 0.97134875, 0.46866302, 0.88366356],
[0.85220647, 0.61853079, 0.45999031, 0.69883963],
[0.7875093 , 0.32514806, 0.80099353, 0.26738617]]])
- randn
- 평균이 0이고, 분산이 1인 정규분포 형태의 랜덤값을 반환
np.random.seed(42)
arr = np.random.randn(10000)
arr
=> array([ 0.49671415, -0.1382643 , 0.64768854, ..., -0.70531672,
0.49576557, 0.64438845])
- randint
- 랜덤한 정수 반환
- start ~ end-1
- 세번째 인자는 크기
np.random.randint(50,100,(4,3))
=> array([[78, 64, 92],
[57, 70, 88],
[68, 72, 60],
[60, 73, 85]])
- shuffle
- 반환값이 없고, 배열 자체를 섞는다.
- 원본 데이터가 섞여서 위험성이 높다.
- arr = arr.copy (깊은 복사를 사용해야한다.)
np.random.seed(42)
arr = np.arange(1,7)
np.random.shuffle(arr)
arr
=> array([1, 2, 6, 3, 5, 4])
- choice
- 지정한 개수만큼 랜덤하게 선택해서 추출
np.random.choice(5,3) # 0~4사이의 값을 3개 뽑음
=> array([3, 1, 3])
axis 이해하기
np.random.seed(42)
arr = np.random.randint(50,91,[4,3])
arr
=> array([[88, 78, 64],
[57, 70, 88],
[68, 72, 60],
[60, 73, 85]])
axis를 이용하여 1차원으로 표현
arr.sum(axis = 0) # 1차원
=> array([273, 293, 297])
즉, axis가 0인 경우 각 행에 첫번째 열을 더하고, 두번째을 더하고, 세번째 열을 더한 것을 나타낸 결과이다.
axis를 이용하여 2차원으로 표현
arr.sum(axis = 1) # 2차원
=> array([230, 215, 200, 218])
이번에는 각 열의 같은행을 더한 것이다.
axis를 이용하여 3차원으로 표현
3차원 배열 생성
np.random.seed(42)
arr = np.random.randint(50,91,[4,3,2])
arr
=> array([[[88, 78],
[64, 57],
[70, 88]],
[[68, 72],
[60, 60],
[73, 85]],
[[89, 73],
[52, 71],
[51, 73]],
[[79, 87],
[51, 70],
[82, 61]]])
결과
arr.sum(axis = 0) # 3행 2열
=> array([[324, 310],
[227, 258],
[276, 307]])
3행 2열인 2차원 구조가 4개가 있는 구조에서 2차원 구조에서 각 같은 행에 같은 열을 더하여 나타낸 것이다.
넘파이의 구조를 이해하는데 오래걸렸다.
내가 머리로는 이해해도 막상 코드를 실행해보면 원하지않게 나올 때가 많았다.
내일 다시 복습하자!
'AI 공부 > 파이썬' 카테고리의 다른 글
파이썬 (Pandas를 이용한 EDA) (0) | 2022.08.30 |
---|---|
파이썬 (Pandas 기초) (0) | 2022.08.30 |
파이썬 (SQLAIchemy) (0) | 2022.08.23 |
파이썬 (Pymysql) (0) | 2022.08.23 |
파이썬 (pip와 가상 환경) 마지막! (0) | 2022.08.10 |
댓글