[Numpy] 배열(Array) 연산

Hunie_07·2026년 2월 26일

Numpy

목록 보기
3/8
post-thumbnail

📌 Array 연산

1️⃣ 기본 연산

  • 기본적으로 동일한 크기의 배열간에 연산을 수행한다.
arr1 = np.array([[1, 3, 4], [4, 2, 6]])
arr2 = np.array([[10, 11, 12], [15, 17, 19]])

1) 배열의 합

arr1 + arr2

- 출력

array([[11, 14, 16],
       [19, 19, 25]])

2) 배열의 차

arr1 - arr2

- 출력

array([[ -9,  -8,  -8],
       [-11, -15, -13]])

3) 배열의 곱

arr1 * arr2

- 출력

array([[ 10,  33,  48],
       [ 60,  34, 114]])

4) 배열의 나눗셈

arr1 / arr2

- 출력

array([[0.1       , 0.27272727, 0.33333333],
       [0.26666667, 0.11764706, 0.31578947]])

5) 배열의 스칼라 연산

합 연산

arr1 + 2

- 출력

array([[3, 5, 6],
       [6, 4, 8]])

차 연산

arr1 - 10

- 출력

array([[-9, -7, -6],
       [-6, -8, -4]])

곱 연산

arr1 * 2

- 출력

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

나눗셈 연산

arr1 / 10

- 출력

array([[0.1, 0.3, 0.4],
       [0.4, 0.2, 0.6]])

6) 배열의 비교 연산

  • 배열의 각 값들의 조건 충족 여부를 값으로 가지는 배열을 출력한다. True / False
arr1 > 4

- 출력

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

2️⃣ 배열 Broadcasting

  • 서로 크기가 다른 배열들도 연산이 가능하도록 배열을 자동적으로 변환하여 연산을 수행한다.
arr1 = np.array([[1, 3, 4], 
				 [4, 2, 6]])
arr3 = np.array([10, 20, 30])
  • 위의 두 배열은 각각 크기가 (2, 3) / (3, ) 으로 다르지만 아래와 같이 연산이 가능하다.
arr1 + arr3

- 출력

array([[11, 23, 34],
       [14, 22, 36]])
  • 마치 arr3 이 크기가 (2, 3) 인 것처럼 변환되어 연산이 수행되었다.

  • 단, 차원의 수 ndim 이 동일하지만 차원의 크기가 다른 경우 연산이 불가능하다.
arr1 = np.array([[1, 3, 4], 
				 [4, 2, 6]])
arr4 = np.array([[1], [2], [3]])
  • 위의 두 배열은 각각 크기가 (2, 3) / (3, 1) 으로 차원의 수는 동일하지만 차원의 크기가 달라 아래와 같은 에러가 발생한다.
arr1 + arr4

- 출력

ValueError: operands could not be broadcast together with shapes (2,3) (3,1) 

브로드캐스팅 조건

  • 뒤에서부터 크기를 비교한다.
    • 두 배열 간의 연산에서 최소한 하나의 배열의 차원이 1 이거나
    • 두 배열의 축의 길이가 같아야 한다.

Ex) (2, 3) 과 (3, 1) 의 경우 뒤에서부터 3 과 1은 1이 있어 가능하나, 2 와 3은 둘 중 하나가 1도 아니고 축의 길이가 같지도 않기 때문에 연산이 불가능한 것이다.


3️⃣ 통계 연산

  • 배열의 합, 평균, 표준편차, 분산, 최소값, 최대값, 누적합, 누적곱 등
arr1 = np.arange(1, 10)
arr2 = np.array([[10, 11, 12],
       			 [15, 17, 19]])

1) 합계 (sum)

arr1.sum()

- 출력

np.int64(45)
  • 2차원도 동일하게 합 연산을 진행한다.
arr2.sum()

- 출력

np.int64(84)

  • axis : 연산을 진행할 기준 축을 설정한다.
    • 2차원 배열
      • 0 : 열을 기준으로 연산을 진행하며, 행방향 (세로) 계산한다.
      • 1 : 행을 기준으로 연산을 진행하며, 열방향 (가로) 계산한다.
    • 3차원 배열
      • 0 : 면을 기준으로 연산을 진행하며, 각 면의 동일한 위치의 요소끼리 계산한다.
      • 1 : 열을 기준으로 연산을 진행하며, 행방향 (세로) 계산한다.
      • 2 : 행을 기준으로 연산을 진행하며, 열방향 (가로) 계산한다.

2차원 열 기준

arr2 = np.array([[10, 11, 12],
       			 [15, 17, 19]])
arr2.sum(axis=0)

- 출력

array([25, 28, 31])

2차원 행 기준

arr2.sum(axis=1)

- 출력

array([33, 51])

  • 3차원의 경우 다소 헷갈릴 수 있지만 아래의 예시를 살펴보자.

3차원 배열

arr3 = np.arange(1, 13).reshape(2, 3, 2)
arr3

- 출력

array([[[ 1,  2],
        [ 3,  4],
        [ 5,  6]],

       [[ 7,  8],
        [ 9, 10],
        [11, 12]]])

3차원 면 기준

  • 위 3차원 배열은 현재 가장 큰 단위의 2개의 리스트 안에 각각 3개의 리스트를 가지고 있으며 각 리스트는 2개의 요소를 가지고 있다.
  • 여기서 가장 큰 단위의 2개의 리스트가 면이 된다. 면 기준으로 연산을 진행할 경우 각 면의 동일한 위치끼리 연산하여 면의 크기를 유지하며 면을 제거한다.
arr3.sum(axis=0)

- 출력

array([[ 8, 10],
       [12, 14],
       [16, 18]])

3차원 열 기준

  • 각 면의 열끼리 연산을 진행한다.
arr3.sum(axis=1)

- 출력

array([[ 9, 12],
       [27, 30]])

3차원 행 기준

arr3.sum(axis=2)

- 출력

  • 각 면의 행끼리 연산을 진행한다.
array([[ 3,  7, 11],
       [15, 19, 23]])

2) 평균 (mean)

arr1.mean()

- 출력

np.float64(5.0)

열 기준

arr2 = np.array([[10, 11, 12],
       			 [15, 17, 19]])
arr2.mean(axis=0)

- 출력

array([12.5, 14. , 15.5])

행 기준

arr2.mean(axis=1)

- 출력

array([11., 17.])

3) 표준편차 (std)

arr1.std()

- 출력

np.float64(2.581988897471611)

4) 분산 (var)

arr1.var()

- 출력

np.float64(6.666666666666667)

5) 최소값 (min)

arr1.min()

- 출력

np.int64(1)

6) 최대값 (max)

arr1.max()

- 출력

np.int64(9)

7) 누적합 (cumsum)

arr1.cumsum()

- 출력

array([ 1,  3,  6, 10, 15, 21, 28, 36, 45])
  • 누적합에서는 3차원 배열 형태가 그대로 유지된다.

3차원 면 기준

arr3 = np.array([[[ 1,  2],
                  [ 3,  4],
                  [ 5,  6]],

                 [[ 7,  8],
                  [ 9, 10],
                  [11, 12]]])
arr3.cumsum(axis=0)

- 출력

array([[[ 1,  2],
        [ 3,  4],
        [ 5,  6]],

       [[ 8, 10],
        [12, 14],
        [16, 18]]])

3차원 열 기준

arr3.cumsum(axis=1)

- 출력

array([[[ 1,  2],
        [ 4,  6],
        [ 9, 12]],

       [[ 7,  8],
        [16, 18],
        [27, 30]]])

8) 누적곱 (cumprod)

arr2 = np.array([[10, 11, 12],
       			 [15, 17, 19]])
arr2.cumprod(axis=1)

- 출력

array([[  10,  110, 1320],
       [  15,  255, 4845]])

4️⃣ 행렬 연산

  • 선형 대수(Linear algebra)를 위한 행렬(2차원 배열) 연산

  • 행렬 곱, 전치 행렬, 역행렬, 행렬식 등

    • 행렬곱(matrix product) : A.dot(B) 혹은 np.dot(A,B)
    • 전치행렬(transpose matrix) : A.transpose() 혹은 np.transpose(A)
    • 역행렬(inverse matrix) : np.linalg.inv(A)
    • 행렬식(determinant) : np.linalg.det(A)

예시 행렬

A = np.array([0, 1, 3, 5, 9, 2]).reshape(2, 3)
B = np.array([3, 2, 0, -10, 11, 4, 2, 7, 5]).reshape(3, 3)
C = np.array([5, 1, 5, 7, 0, -1]).reshape(3, 2)
# A
array([[0, 1, 3],
       [5, 9, 2]])
# B
array([[  3,   2,   0],
       [-10,  11,   4],
       [  2,   7,   5]])
# C
array([[ 5,  1],
       [ 5,  7],
       [ 0, -1]])

1) 행렬의 곱 (dot)

  • 왼쪽행렬의 열과 오른쪽 행렬의 행의 크기가 같아야 연산 가능
  • (a x b) 행렬과 (c x d) 행렬의 곱은 b = c 여야 하며, 곱의 결과는 (a x d) 행렬이다.

각 행렬의 크기 확인

A.shape, B.shape, C.shape

- 출력

((2, 3), (3, 3), (3, 2))

행렬의 곱1

A.dot(B)

- 출력

array([[ -4,  32,  19],
       [-71, 123,  46]])

행렬의 곱 (불가능)

  • B 행렬은 (3 x 3) 행렬이고, A 행렬은 (2 x 3) 행렬이라 2 ≠ 3 이므로 에러 발생한다.
B.dot(A)

- 출력

ValueError: shapes (3,3) and (2,3) not aligned: 3 (dim 1) != 2 (dim 0)

행렬의 곱2

np.dot(A, B)

- 출력

array([[ -4,  32,  19],
       [-71, 123,  46]])

2) 전치행렬 (transpose)

  • 행과 열의 위치를 바꿔주는 연산이다.
# A
array([[0, 1, 3],
       [5, 9, 2]])
       
# A.transpose()
array([[0, 5],
       [1, 9],
       [3, 2]])

# A.T
array([[0, 5],
       [1, 9],
       [3, 2]])
       
# np.transpose(A)
array([[0, 5],
       [1, 9],
       [3, 2]])

3) 역행렬 (inverse)

  • 역행렬을 구해주는 연산으로, 기존 행렬과 역행렬을 곱하면 단위행렬이 된다.

예시 행렬

D = np.array([1, 2, -10, 4]).reshape(2, 2)
D

- 출력

array([[  1,   2],
       [-10,   4]])

역행렬 연산

D_inv = np.linalg.inv(D)
D_inv

- 출력

array([[ 0.16666667, -0.08333333],
       [ 0.41666667,  0.04166667]])
  • 실제로 두 행렬을 곱해보면 단위행렬이 된다.
np.dot(D, D_inv)

- 출력

array([[ 1.00000000e+00,  1.38777878e-17],
       [-2.22044605e-16,  1.00000000e+00]])

4) 행렬식 (determinant)

np.linalg.det(D)

- 출력

np.float64(24.000000000000004)

0개의 댓글