본문 바로가기

코딩/데이터분석

[Python/파이썬] Numpy 기초 2편 : numpy의 여러가지 연산

반응형

 

※ 관련포스팅

1편 : 2021.06.29 - [코딩/Python] - [Python/파이썬] Numpy 기초 1편 : Array 생성 및 인덱싱,슬라이싱

2편 : 2021.06.30 - [코딩/Python] - [Python/파이썬] Numpy 기초 2편 : numpy의 여러가지 연산

 

 

  이번 편에서는 numpy의 각종 연산에 대한 부분을 알아본다. numpy의 행렬 계산은 우리가 일반적으로 알고 있는 선형대수 행렬 계산 외에 브로드캐스팅이라는 개념이 존재한다. 참고링크의 예시들을 따라하며 공부해 본 내용을 정리해보았다.

 

 

1. 행렬 크기가 서로 같은 경우의 연산

 

 

  아래와 같이 2*2의 2차원 행렬 2개(t1, t2)를 정의해보았다. 행렬 크기가 같은 경우 어떻게 계산이 이루어지는지 아래 여러가지 예시를 통해 공부하였다.

 

 

<코드>

# Case1. 크기가 같은 경우의 연산
t1 = np.array([[1,2],[3,4]]) #2*2 행렬 선언 t1
t2 = np.array([[1,2],[3,4]]) #2*2 행렬 선언 t2

 

<결과>

#t1
array([[1, 2],
       [3, 4]])
       
#t2
array([[1, 2],
       [3, 4]])

 

 

1) 행렬 덧셈

 

 

<코드>

t1+t2 #행렬 덧셈

 

<결과>

array([[2, 4],
       [6, 8]])

 

 

2) 행렬 뺄셈

 

 

<코드>

t1-t2 #행렬 뺄셈

 

<결과>

array([[0, 0],
       [0, 0]])

 

 

3) 행렬 곱셈(element-wise 곱셈) : 요소별 곱셈

 

 

  numpy의 행렬 곱셈은 일반적으로 알고있는 선형대수의 행렬 곱이 아니다. element-wise 라고 하며, 같은 위치 요소의 곱으로 이루어진다. 아래 결과를 확인해보자.

 

 

<코드>

#numpy 행렬의 곱셈은 행렬 곱이 아닌 같은 위치 요소의 곱으로 이루어진다.(element-wise 곱셈)
t1*t2 

 

<결과>

array([[ 1,  4],
       [ 9, 16]])

 

 

4) 나눗셈

 

  나눗셈은 곱셈과 마찬가지로 element-wise로 계산되므로 추가 설명을 생략한다.

 

<코드>

t1/t2 #나눗셈도 마찬가지로 element-wise

 

<결과>

array([[1., 1.],
       [1., 1.]])

 

 

5) 행렬 곱셈(dot) : 선형대수학 행렬 곱셈

 

  우리가 선형대수학에서 배우는 행렬 곱셈은 dot 함수를 통해 구할 수 있다.

 

<코드>

#행렬곱은 dot 함수에 의해 구해진다.
t1.dot(t2)

 

<결과>

array([[ 7, 10],
       [15, 22]])

 

 

 

2. 브로드캐스팅(Broadcasting)

 

 

  numpy 행렬 연산에서는 브로드캐스팅(Broadcasting)이라는 개념이 있다. 선형대수학에서의 행렬 합, 차이를 구할 때는 두 행렬의 크기가 같아야 한다. numpy에서는 두 행렬의 크기가 달라도 자동으로 크기가 큰 행렬 기준으로 확장하여 계산하여 준다. 아래 예시를 통해 알아보자.

 

 

<코드>

#브로드캐스팅 연산을 위한 행렬 정의
t3 = np.array([[1,2,3]]) #(1,3) : 2차원
t4 = np.array([3])  #(1,) : 1차원

 

 

1) 크기가 다른 행렬 합계

 

 

  위와 같이 크기와 차원이 달라도 numpy 행렬의 합계는 자동으로 브로드캐스팅이 적용되어 t4의 행렬이 아래와 같이 변경되어 계산된다.

 

#t4 의 확장
[3] -> [3] [3] [3]

 

<코드>

# 브로드캐스팅 합계 t4 : (1,) -> 동일한 요소의 (1,3)으로 변경하여 계산
# 원래 행렬의 연산은 크기가 같은 행렬에 대해서만 계산이 가능하지만 numpy는 브로드캐스팅이 있다.
t3+t4

 

<결과>

array([[4, 5, 6]]) #(3,1) : 2차원

 

  따라서 위 결과처럼 t3 행렬에 각각 [3]이 더해져 2차원 행렬인 [[4,5,6]]이 출력된다.

 

 

2) 크기가 다른 행렬 곱셈

 

 

  곱셈을 설명하기 위해 새로운 행렬 t5, t6을 선언해보았다.

 

 

<코드>

t5 = np.array([[1,2,3],[4,5,6]])
t6 = np.array([[1],[2]])

 

<t5, t6 출력>

#t5 : (3,2) 2차원 행렬
array([[1, 2, 3],
       [4, 5, 6]])

#t6 : (2,1) 2차원 행렬
array([[1],
       [2]])

 

 

  위에서 언급했던대로 크기가 같은 행렬이라면 element-wise로 각각 요소의 곱으로 계산되지만, 크기가 다른 곱셈 적용시 브로드캐스팅이 적용된다.

 

 

<코드>

 # numpy의 행렬곱셈은 같은 요소의 곱으로 이루어지나 위처럼 크기가 다른경우 자동으로 브로드캐스팅되어 계산 됨.
t5 * t6

 

<결과>

array([[ 1,  2,  3],
       [ 8, 10, 12]])

 

 


3. 그 밖의 함수 연산

  

 

 1) 최대값, 최소값

 

 

   numpy의 행렬 요소 중 최대값, 최소값을 구하려면 max( ), min( ) 함수를 사용하자. 차원, 크기와 상관없이 최대값, 최소값을 출력한다. numpy array는 위 의 t5를 활용한다.

 

 

#t5
array([[1, 2, 3],
       [4, 5, 6]])

 

 

<코드>

print("최대값 : ", t5.max())
print("최소값 : ", t5.min())

 

<결과>

최대값 :  6
최소값 :  1

 

 

  차원 연산이 필요한 경우 axis라는 파라미터를 통해 차원별 연산을 수행할 수 있다. 위 처럼 아무 것도 지정안한 경우 axis=0이 디폴트값이라고 생각하면 된다.

 

axis = 0 : 열 연산
axis = 1 : 행 연산
axis = 2 : 3차원 연산

 

아래 그림은 axis를 이해하기 위한 이미지이다. 참고!

 

axis 파라미터에 따른 차이

 

  위 t5 행렬에 최대값, 최소값을 axis에 따라 어떻게 계산되는지 확인해보면 아래 결과처럼 axis=0일 경우에 행별 계산으로 인한 1차원 벡터, axis=1일 경우에 열별 계산으로 인한 1차원 벡터를 구할 수 있다.

 

<코드>

#행연산 최대값(결과는 행의 각 요소를 비교한 1차원 벡터임)
print("행연산 최대값", t5.max(axis=0))

#열연산 최소값(결과는 열의 각 요소를 비교한 1차원 벡터임)
print("열연산 최소값", t5.min(axis=1))

 

<결과>

행연산 최대값 [4 5 6]
열연산 최소값 [1 4]

 

 

2) 요소 합계 sum( )

 

 

  행렬 모든 요소의 합계를 구하는 sum이다. max, min과 마찬가지로 axis 파라미터 설정에 따른 계산값을 확인할 수 있다.

 

 

<코드>

print("모든 요소 합계 : ", t5.sum()) #요소의 총합계
print("행 합계 : ", t5.sum(axis=0)) #요소의 열합계
print("열 합계 : ", t5.sum(axis=1)) #요소의 행합계

 

<결과>

모든 요소 합계 :  21
행 합계 :  [5 7 9]
열 합계 :  [ 6 15]

 

 

3) 평균 mean( ) 과 중간값 median( )

 

 

  요소의 평균이나 중간값을 구할 수도 있다. 주의할 점은 중간값의 경우 요소의 개수가 짝수이면 중간에 위치한 숫자 2개의 평균을 계산한다. 중간값의 경우 numpy.median(array) 형식으로 사용하므로 문법에 주의하도록 하자.

 

<코드>

print("평균 : ", t5.mean())
print("중간값 : ", np.median(t5))

 

<결과>

평균 :  3.5
중간값 :  3.5

 

t5의 요소가 짝수개이므로 (1,2,3,4,5,6) 중 중간 숫자 3,4의 평균값인 3.5가 결과값이다. 

 


4) 최대값, 최소값 인덱스 구하기 : argmax( ), argmin( )

 

 

  한 행렬의 최대값, 최소값 인덱스를 구하려면 argmax( )와 argmin( )을 사용한다. 인덱스는 0부터 시작하여 최대값과 최소값의 인덱스 번호를 출력하게 된다.

 

 

<코드>

print("최대값 인덱스 :", t5.argmax()) #최대값의 인덱스 출력
print("최소값 인덱스 :", t5.argmin()) #최소값의 인덱스 출력

 

<결과>

최대값 인덱스 : 5
최소값 인덱스 : 0

 

인덱스 참고

 

 

 

4. 논리 연산

 

 

  논리 연산은 두개의 행렬을 비교하여 bool type의 결과(True, False)를 행렬로 출력해주는 부분이다. 여러가지 내용이 있으나 간단히 필요한 내용만 정리하고 자세한 내용은 하단의 참고링크로 대체한다.

 

  비교를 위한 간단하게 (1,2) 행렬 2개를 선언해보았다.

 

 

<코드>

v1 = np.array([[1],[3]]) #(1,2) 2차원 행렬 
v2 = np.array([[1],[2]]) #(1,2) 2차원 행렬

 

V1, V2 행렬

 

 

1) 행렬 비교 연산

 

 

  말 그대로 2개의 행렬의 각 요소를 비교하여 각각 같은지 Boolean type으로 결과를 반환한다.

 

 

<코드>

v1 == v2

 

<결과>

array([[ True],
       [False]])

 

 

만약 2개의 행렬이 완전히 같은 행렬인지 아닌지 비교하여 하나의 출력값으로 받고 싶다면 all 함수를 사용한다.

 

 

<코드>

np.all(v1==v2)

 

<결과>

False

 


2) 브로드캐스팅 비교 연산

 

 

  다른 크기의 행렬 비교시에도 numpy는 브로드캐스팅을 적용하여 자동으로 연산한다. 위에서 정의했던 t5, t6 행렬을 그대로 가져와보았다.

 

#t5
array([[1, 2, 3],
       [4, 5, 6]])
       
#t6
array([[1],
       [2]])

 

<코드>

t5 == t6 #논리 연산시에도 자동으로 브로드캐스팅하여 연산 된다.

 

<결과>

array([[ True, False, False],
       [False, False, False]])

 

 

위 결과에서 보듯이 크기가 작은 t6 행렬을 자동을 브로드캐스팅하여 크기가 큰 t5 기준인 (2,3)으로 만든다.

 

[1] -> [1] [1] [1]
[2] -> [2] [2] [2]

 

 


참고링크

1. https://ebbnflow.tistory.com/159

 

[파이썬패키지] 딥러닝을 위한 Numpy2 - 행렬의 연산

앞선 포스팅에서 2020/03/05 - [SW개발/Framework Library] - [파이썬패키지] 딥러닝을 위한 Numpy 공부1 - Numpy기초 [파이썬패키지] 딥러닝을 위한 Numpy 공부1 - Numpy기초 ● Numpy란 넘파이(Numpy)는 C로 구..

ebbnflow.tistory.com

 

2. '파이토치로 시작하는 딥러닝 입문' -  https://wikidocs.net/52460

 

위키독스

온라인 책을 제작 공유하는 플랫폼 서비스

wikidocs.net

 

728x90