[Numpy 심화] - 1

임동윤·2022년 10월 3일
0
post-thumbnail

np.matmul() 함수

  • Numpy dot 메소드에서 np.dot()함수를 사용하여 행렬 곱 연산을 했습니다. 그러나 3, 4차원의 배열에서 np.dot()을 사용하여 연산을 하면 의도치 않은 결과가 도출될 수 있습니다.
  • 고차원 배열에서 Numpynp.dot()np.matmul()메소드를 살펴보고 둘의 차이점에 대해 알아봅시다.

np.dot()와 np.matmul()의 차이

  • 2 x 2 x 2 모양을 가진 3차원 두 배열을 생성하고 np.dot()np.matmul()를 사용하여 연산해보겠습니다.
>>> import numpy as np

>>> A = np.array([
        [[3, 1], 
        [3, 3]], 

        [[1, 1], 
        [3, 2]]])
>>> B = np.array([
        [[3, 3],
        [3, 3]],

        [[1, 3],
        [2, 1]]])

>>> print(np.dot(A, B))
[[[[12 12]
   [ 5 10]]

  [[18 18]
   [ 9 12]]]


 [[[ 6  6]
   [ 3  4]]

  [[15 15]
   [ 7 11]]]]

>>> print(np.matmul(A, B))
[[[12 12]
  [18 18]]

 [[ 3  4]
  [ 7 11]]]

np.dot() 연산 과정

  • np.dot()은 각 A의 행 벡터와 B의 열 벡터끼리 모두 내적 연산을 합니다.

np.matmul() 연산 과정

  • np.matmul()은 뒤에서 2개의 차원에 해당하는 배열끼리 행렬 곱 연산을 합니다.


브로드캐스팅 스칼라

  • 배열과 상수의 연산에서 어떻게 브로드캐스팅이 적용되는지 살펴봅시다.

스칼라

  • 스칼라란 단일 차원(0차원)의 값을 의미합니다. 즉, 방향이 없고 오로지 크기만을 가지는 값으로 상수로 표현이 가능합니다.

배열과 상수 사이의 덧셈 연산

  • 3 x 3 배열에 10을 더하는 코드를 살펴보겠습니다.
>>> import numpy as np

>>> A = [
     [1, 1, 1],
     [2, 2, 2],
     [3, 3, 3]
   ]
>>> A = np.array(A)
>>> result = A + 10
>>> print(result)
[[11 11 11]
 [12 12 12]
 [13 13 13]]

  • 상수 10A의 모양에 맞춰 3 x 3의 모양을 가진 2차원의 배열로 확장됩니다. 그리고 각 요소별로 덧셈 연산을 행합니다. 이는 덧셈 뿐만 아니라 곱셈, 나눗셈, 뺄셈, 그리고 나머지 연산에도 적용됩니다.

브로드캐스팅 - 같은 차원의 다른 모양

  • 같은 차원이지만 다른 모양을 가진 배열 간의 연산에서 어떻게 브로드캐스팅이 적용되는지 살펴봅시다.

같은 차원의 다른 모양을 가진 2차원 배열(행렬)의 경우

  • 2차원 배열(행렬) 간의 덧셈 연산을 해봅시다. 예시로 3 x 3 배열(A)과 1 x 3 배열(B) 사이에 덧셈 연산, 그리고 3 x 3 배열(A)과 2 x 3 배열(C) 사이에 덧셈 연산을 행하는 코드를 살펴보겠습니다.
>>> import numpy as np

>>> A = [
    [10, 10, 10],
    [20, 20, 20],
    [30, 30, 30]
]
>>> B = [
    [1, 2, 3]
]
>>> C = [
    [2, 2, 3],
    [4, 5, 6],
]
>>> A = np.array(A)
>>> B = np.array(B)
>>> C = np.array(C)
>>> result = A + B
>>> print(result)
[[11 12 13]
 [21 22 23]
 [31 32 33]]

>>> result = A + C
ValueError: operands could not be broadcast together with shapes (3,3) (2,3)

  • 1 x 3 배열 B는 3 x 3 배열 A 모양의 맞춰 0차원을 기준으로 확장(1->3)하여 연산합니다.
  • 그러나 2 x 3 배열 C는 3 x 3 배열 A 모양에 맞추지 못한다고 에러가 발생합니다. 이는 브로드캐스팅이 차원의 크기가 1일 때만 적용이 되기 때문입니다. 따라서 B는 0차원의 크기가 1이여서 브로드캐스팅이 적용되지만, C는 0차원의 크기가 2이므로 브로드캐스팅이 적용되지 않습니다.

브로드캐스팅 - 다른 차원의 배열

  • 차원이 다른 배열들 간의 연산을 할 때 브로드캐스팅이 어떻게 적용되는지 살펴봅시다.

차원이 다른 배열 간의 연산

  • 다른 차원의 배열들 간의 연산을 해봅시다. 예시로 2 x 1 x 3 모양을 가진 3차원 배열(A)과 2 x 3 모양을 가진 2차원 배열(B) 사이에 덧셈 연산, 그리고 배열(A)과 1 x 2 모양을 가진 2차원의 배열(C) 사이에 덧셈 연산을 하는 코드를 살펴보겠습니다.
>>> import numpy as np

# 2 x 1 x 3 모양의 배열 A
>>> A = np.array(
    [[[3, 2, 1]],
     [[0, 1, 3]]]
)
# 2 x 3 모양의 배열 B
>>> B = np.array(
    [[0, 2, 1],
     [2, 2, 3]]
)
# 2 모양의 배열 C
>>> C = np.array([[1, 2]])

>>> result = A + B
>>> print(result)
[[[3 4 2]
  [5 4 4]]

 [[0 3 4]
  [2 3 6]]]

>>> result = A + C
ValueError: operands could not be broadcast together with shapes (2,1,3) (1,2) 

  • 2 x 3 모양을 가진 2차원 배열 B는 0차원의 크기가 2, 1차원의 크기가 3입니다. 그러나 2 x 1 x 3 모양을 가진 3차원의 배열 A에 맞춰 3차원으로 확장되면 0차원에는 배열 A의 0차원 크기인 2가 되고, 1차원에는 기존 배열의 0차원 크기(2)가, 2차원에는 기존 배열의 1차원 크기(3)가 됩니다.
  • 실습에서 확인했던 것처럼 배열 A의 1차원의 크기가 1이므로 배열 B의 1차원의 크기에 맞춰 2로 확장됩니다.
  • 그러나 A + C의 경우 브로드캐스팅이 적용되지 않는다고 에러가 발생합니다. 이는 브로드캐스팅이 적용될 때 마지막 차원부터 맞춰지기 때문입니다. 즉, 배열 A의 2차원의 크기인 3과 C의 1차원의 크기인 2가 맞지 않아 발생한 것입니다.

브로드캐스팅 정리

  • 브로드캐스팅 적용 조건에 대해서 정리해봅시다.

브로드캐스팅 적용 조건

  1. 같은 레벨의 차원끼리 비교했을때 크기가 다르더라도 차원의 크기가 1이면 브로드캐스팅이 가능하다.

  1. 차원의 레벨이 다르더라도 뒤에서부터 비교하여 크기가 같거나 차원의 크기가 1이면 브로드캐스팅이 가능하다.

  • 위 두가지 조건을 벗어난 배열 간의 연산에서는 브로드캐스팅을 할 수 없습니다.

any(), all()

  • 배열을 검사해주는 any()와 all()메소드에 대해 살펴봅시다.

any() 메소드

  • any()메소드는 주어진 배열에 True가 하나라도 있으면 True를 반환하고, True가 하나도 없다면 False를 반환합니다. 예시로 배열에 4 이상의 수가 있는지 검사하는 코드를 살펴봅시다.
>>> import numpy as np

>>> A = np.array([1, 2, 3, 4, 5, 4, 3, 2, 1])
>>> print(A >= 4)
[False False False  True  True  True False False False]

>>> print((A >= 4).any())
True

all() 메소드

  • all()메소드는 주어진 배열의 모든 요소가 True라면 True를 반환하고, 하나라도 False가 있다면 False를 반환합니다. 위에서 살펴본 코드에 any() 대신 all()을 넣어보겠습니다.
>>> import numpy as np
>>> A = np.array([1, 2, 3, 4, 5, 4, 3, 2, 1])
>>> print(A >= 4)
[False False False  True  True  True False False False]

>>> print((A >= 4).all())
False

profile
AI Tensorflow Python

1개의 댓글

comment-user-thumbnail
2023년 9월 16일

np.matmul() 연산과정 결과에서 2번째 행의 결과가
a111b111 + a112b121 a111b112 + a112b122 인데
a121b111 + a121b121 a121b112 + a122b122 를 잘 못 쓰신건가요?

답글 달기