[Python으로 데이터 다루기 I - numpy]1강:Numpy의 연산

3 minute read

Numpy로 연산하기

Vector와 Scalar 사이의 연산

벡터와 각 원소에 대해 연산을 진행

import numpy as np
x = np.array([1, 2, 3])
c = 5
print("더하기 : {}".format(x + c)) # {}안에 format의 변수를 넣어준다.
print("빼기 : {}".format(x + c))
print("곱하기 : {}".format(x + c))
print("나누기 : {}".format(x + c))
더하기 : [6 7 8]
빼기 : [6 7 8]
곱하기 : [6 7 8]
나누기 : [6 7 8]



Vector와 Vector 사이의 연산

벡터의 같은 인덱스끼리 연산이 진행된다.

y = np.array([1, 3, 5])
z = np.array([2, 9, 20])
print("더하기 : {}".format(y + z))
print("빼기 : {}".format(y + z))
print("곱하기 : {}".format(y + z))
print("나누기 : {}".format(y + z))
더하기 : [ 3 12 25]
빼기 : [ 3 12 25]
곱하기 : [ 3 12 25]
나누기 : [ 3 12 25]



Array의 Indexing

Array에서 특정 위치의 원하는 원소를 가지고 오고 싶다면?
Python의 List와 유사하게 진행.
파이썬과 다른 점은, 2차원 이상의 배열에서 A[a][b]와 같이 접근하지 않고 A[a,b]이렇게 한 괄호 안에서 다 써준다는 점이다.

W = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
print(W[0, 0]) # 1
print(W[2, 3])# 12
1
12



Array의 Slicing

Python의 리스트와 유사하게 진행

W = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
print(W[0:2, 1:3]) # 행 : 인덱스 0~1, 열 : 인덱스 1~2
[[2 3]
 [6 7]]
print(W[0:2, 0:4]) # 모든 행과 열을 가져옴
print(W[0:2]) # 모든 행과 열을 가져옴
print(W[0:2, :]) # 모든 행과 열을 가져옴
[[1 2 3 4]
 [5 6 7 8]]
print(W[0:3, 2:4]) # 모든 행과 열 뒤에서 두개
print(W[:,2:4]) # 모든 행과 열 뒤에서 두개
[[ 3  4]
 [ 7  8]
 [11 12]]



Array의 Broadcasting

Numpy가 연산을 진행하는 특수한 방법!

  1. $M * N$, $M * 1$ 서로 차원이 다른 배열의 계산도 가능하다.
    $ \begin{bmatrix} \1 & 2 & 3\cr \4 & \5 & 6\cr \7 & \8 & \9 \end{bmatrix} + \begin{bmatrix} 0\cr 1\cr 0 \end{bmatrix} $
    이라는 행렬 계산이 있으면, (션형대수적으로는)불가능하지만, numpy에서는 다음과 같이 취급하여 계산이 가능하다.
    $ \begin{bmatrix} \1 & 2 & 3\cr \4 & \5 & 6\cr \7 & \8 & \9 \end{bmatrix} + \begin{bmatrix} 0 & 0 & 0\cr 1 & 1 & 1\cr 0 & 0 & 0 \end{bmatrix} = \begin{bmatrix} 1 & 2 & 3\cr 5 & 6 & 7\cr 7 & 8 & 9 \end{bmatrix} $

  2. $M * N$, $1 * N$ $ \begin{bmatrix} \1 & 2 & 3\cr \4 & \5 & 6\cr \7 & \8 & \9 \end{bmatrix} * \begin{bmatrix} 0 & 1 & -1\cr \end{bmatrix} $
    이라는 행렬 계산이 있으면, numpy에서는 다음과 같이 취급하여 계산이 가능하다.
    $ \begin{bmatrix} \1 & 2 & 3\cr \4 & \5 & 6\cr \7 & \8 & \9 \end{bmatrix} * \begin{bmatrix} 0 & 1 & -1\cr 0 & 1 & -1\cr 0 & 1 & -1 \end{bmatrix} = \begin{bmatrix} 0 & 2 & -3\cr 0 & 5 & -6\cr 0 & 8 & -9 \end{bmatrix} $
    여기서의 곱셈은 행렬곱이 아니라 elementwise곱이다.

  3. $M * 1$, $1 * N$ $ \begin{bmatrix} \1 \cr \2 \cr \3 \end{bmatrix} + \begin{bmatrix} 2 & 0 & -2\cr \end{bmatrix} $
    이라는 행렬 계산이 있으면, numpy에서는 다음과 같이 취급하여 계산이 가능하다.
    $ \begin{bmatrix} \1 & 1 & 1\cr \2 & \2 & 2\cr \3 & \3 & \3 \end{bmatrix} + \begin{bmatrix} 2 & 0 & -2\cr 2 & 0 & -2\cr 2 & 0 & -2 \end{bmatrix} = \begin{bmatrix} 3 & 1 & -1\cr 4 & 2 & 0\cr 5 & 3 & 1 \end{bmatrix} $


기본적으로 같은 Type의 data에 대해서만 연산이 적용 가능. 하지만 만약에 피연산자가 연산 가능하도록 변환이 가능하다면 연산이 가능하다. 이를 Broadcasting이라고 한다.

  1. $M * N$, $M * 1$
    a = np.array([[1,2,3], [4,5,6], [7,8,9]])
    x = np.array([0,1,0])
    x = x[:, None] # np.array는 기본적으로 행벡터이다. 따라서 열벡터 변형을 위해 transpose를 해준다.
    print(a+x)
    
    [[1 2 3]
     [5 6 7]
     [7 8 9]]
    
  2. $M * N$, $1 * N$
    y = np.array([0, 1, -1])
    print([a*y])
    
    [array([[ 0,  2, -3],
        [ 0,  5, -6],
        [ 0,  8, -9]])]
    
  3. $M * 1$, $1 * N$
    t = np.array([1,2,3])#열벡터로 바꿔줘야 함
    t = t[:, None] # Transpose
    u = np.array([2,0,-2])
    print(t+u)
    
    [[ 3  1 -1]
     [ 4  2  0]
     [ 5  3  1]]