본문 바로가기
머신러닝 딥러닝

0817 Numpy5

by 대금부는개발자 2021. 8. 17.
SMALL

사칙연산, 행렬곱

 


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

 

 

 

 

LIST

'머신러닝 딥러닝' 카테고리의 다른 글

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

댓글