사칙연산, 행렬곱
import numpy as np
arr1 = np.array([[1,2,3],[4,5,6]]) # 2 x 3 ndarray
arr2 = np.arange(10,16,1).reshape(2,3).copy()
print(arr1)
#[[1 2 3]
#[4 5 6]]
print(arr2)
#[[10 11 12]
#[13 14 15]]
같은 shape일 경우 연산 수행이 가능
print(arr1> arr2)
[[False False False]
[False False False]]
a = [1,2,3]
b = [4,5,6]
print(a+b) #python의 list 인 경우 concatenate
행령곱 연산 (matrix multiplication)
행렬이라 함은 기본적으로 행과 열로 구성되어 있으므로 2차원
행렬곱 연산에서 첫 번째 행렬의 열의 개수랑 두 번째 형렬의 행의 개수랑 같아야 해요.
a = np.array([[1,2],[3,4],[5,6]]) # 3 x 2
b = np.array([[1,2,3],[4,5,6]]) # 2 x 3
print(np.matmul(a,b))
[[ 9 12 15]
[19 26 33]
[29 40 51]]
broadcasting
import numpy as np
arr1 = np.array([[1,2,3],
[4,5,6]]) # 2 x 3 2차원 ndarray
arr2 = np.array([1,2,3]) #1차원 ndarray
arr1과 arr2에 대해서 사칙연산을 수행하고 싶어요!
shape이 같아야 연산이 수행될 수 있어요!
arr1 + arr2
array([[2, 4, 6],
[5, 7, 9]])
arr1 = np.array([[1,2,3],
[4,5,6]]) # 2 x 3 2차원 ndarray
arr2 = np.array([1,2]) #1차원 ndarray
arr1 + arr2
# # 에러가 나요! broadcasting 은 배수로 넘어가야 가능해요 scaler(단일 숫자)는 broadcasting 이 쉬워요.
또한 np.matmul(행렬곱) 연산에서는 broadcasting 이 발생하지 않아요!
반복문을 사용하고 싶어요
for, while
1차원 데이터 면 그냥 지금까지 했던 것처럼 for나 while을 사용하면 돼요!
2차원 데이터 면 for 문이 2번 돌아야 해요.
3차원 데이터 면 for 문이 3번 돌아야 해요. → 시간도 오래 걸리고 로직도 복잡해져요.
ndaaray에 대해서 반복 처리를 할 때는 Iterator(반복자)를 이용하는 걸 권장해요!
iternext()라는 함수와 finished라는 속성을 이용해서 ndarray의 모든 요소를 반복적으로 access 할 수 있어요.
import numpy as np
1차원 ndarray
arr = np.array([1,2,3,4,5])
#일반적인 for문을 이용한 ndarray access
for tmp in arr:
print(tmp, end=' ') # 1 2 3 4 5
# Iterator(반복자)를 이용한 1차원 ndarray access
it = np.nditer(arr, flags=['c_index']) #'c_index' 는 1차원에서 정해져 있는 값
# 지정된 flag의 형태를 가지는 Iterator를 추출 'c_index'는 정해져 있는 값 c는 프로그램 언어 c 언어의 c
# 이렇게 만든 Iterator로부터 우리가 index를 추출할 수 있는데 이 index의 형태가 c언어의 index형태와 같다.
# 단 Iterator가 숫자라는 의미가 아니에요. 숫자는 index라는 거고 이 인덱스는 Iterator로부터 추출돼요.
#반복자(Iterator)라는 개념이 현재 어느 위치를 가리키고 있는 거고 몇 번째를 반복하는지 정보를 가지고 있어요.
# Iterator의 finished를 이용하면 반복이 끝났는지를 알 수 있어요!
while not it.finished:
# 아직 반복을 시작하지 않았기 때문에 false가 되어 반복이 되지 않기 때문에 not을 적어줘요.
그래서 while not 은 True가 되어 Iterator가 끝나지 않을 동안 도는 거예요.
idx = it.index # 아직 반복을 시작하지 않아 현재 Iterator가 가르키는 곳은 첫 번째 칸 0이에요
print(arr[idx], end=' ') #현재 1을 가리켜요
it.iternext() # iternext 을 이용해 다음 인덱스로 이동! 2부터 5까지 반복하며 가리켜요.
#1 2 3 4 5
1차원 Iterator의 기본 형태
import numpy as np
arr = np.array([1,2,3,4,5])
it = np.nditer(arr, flags=['c_index'])
while not it.finished:
idx = it.index
print(arr[idx], end=' ')
it.iternext()
#1 2 3 4 5
2차원 ndarray
arr = np.array([[1,2,3],
[4,5,6]]) # shape => (2,3)
for tmp1 in range(arr.shape[0]):
for tmp2 in range(arr.shape[1]):
#하나의 행에 대해 세 번을 돌아야 각 열에 대한 값을 꺼낼 수 있어 중첩 for문 사용
# 2차원으로 바뀌면 기본적으로 루프를 중첩해야 해서 시간이 오래 걸려요.
print(arr[tmp1, tmp2], end=' ') # 1 2 3 4 5 6
Iterator(반복자) 이용
import numpy as np
arr = np.array([[1,2,3],
[4,5,6]])
it = np.nditer(arr, flags=['multi_index'])
# 이 index의 형태는 c언어의 index형태가 아니에요 multi index이기 때문에 tuple 형태로 나와요
while not it.finished:
idx = it.multi_index
print(arr[idx], end=' ')
it.iternext() # 1,2,3,4,5,6
# ndarray는 다양한 집계 함수를 제공해줘요!
import numpy as np
arr = np.arange(1,7,1).reshape(2,3).copy()
print(arr)
print(arr.sum()) # 21
print(np.sum(arr)) # 21 합
print(np.mean(arr)) # 3.5 평균
print(np.max(arr)) # 6 최댓값
print(np.min(arr)) # 1 최솟값
print(np.argmax(arr)) # 5 1차원으로 펼쳐 0부터 시작해서 5번째라는 의미, 최댓값을 찾아서 그 최댓값의 index(1,2)
print(np.std(arr)) # 1.707825127659933 표준편차
numpy의 모든 집계 함수는 axis(축)를 기준으로 계산해요.
위의 예처럼 axis를 명시하지 않으면 axis는 None으로 설정돼요.
이런 경우 집계 함수의 대상은 전체 ndarray로 간주해요.
1차원 ndarray인 경우
arr = np.array([1,2,3,4,5])
print(arr.sum(axis=0)) # 15, 1차원은 열로 구성되어 있어요. 1차원인 경우 축의 번호는 0이고 이때 0의 의미는 열(열 방향)이에요.
2차원 ndarray인 경우
arr = np.array([[1,2,3],[4,5,6]])
print(arr.sum(axis=0)) # [5 7 9]
# 2차원에서는 축의 번호는 0과 1을 쓸 수 있고 0이 행, 1이 열 이에요. 행 방향 이기 때문에 위에서 아래로 더해요
arr = np.array([[1,2,3],[4,5,6],[7,8,9]])
print(arr)
[[1 2 3]
[4 5 6]
[7 8 9]]
print(arr.argmax(axis=1)) #[2 2 2] 열 방향으로 큰 인덱스 번호
3차원 ndarray인 경우
np.random.seed(1)
arr = np.random.randint(0,5,(2,2,3))
print(arr)
print(arr.sum(axis=0)) #3차원에서는 0이 면 방향
[[3 5 4]
[5 4 2]]
간단한 문제를 하나 풀어보아요!
랜덤으로 정수형 난수를 생성할 거예요.
만들어지는 정수형 난수의 범위는 1(포함) ~ 10(포함) 총 12개 생성해서
3행 4열 2차원 ndarray로 만들 거예요!
ndarray 안에 있는 난수 중 5 이상인 숫자들의 합을 구해서 출력하세요.
import numpy as np
np.random.seed(1)
arr = np.random.randint(1,11, (3,4))
# print(arr)
# [[ 6 9 10 6]
# [ 1 1 2 8]
# [ 7 10 3 5]]
print(arr[arr >=5].sum()) # 61
'머신러닝 딥러닝' 카테고리의 다른 글
| 0818 Numpy 7 concatenate(),delete() (0) | 2021.08.18 |
|---|---|
| 0818 Numpy 6 (0) | 2021.08.18 |
| 0817 Numpy4 (0) | 2021.08.17 |
| 0816 Numpy 3 (0) | 2021.08.16 |
| 0816 Numpy2 (0) | 2021.08.16 |
댓글