파이썬 Numpy

Soonyoung Kim·2021년 1월 6일
0
  • 라이브러리 설치

    pip install <라이브러리 이름>

1. numpy

  • 머신러닝 코드 개발 할 경우 자주 사용되는 벡터, 행렬 등을 표현하고 연산할 때 반드시 필요한 라이브러리
  • numpy vs list
    - 머신러닝에서 숫자, 사람, 동물 등의 인식을 하기 위해서는 이미지 데이터를 행렬로 변환하는 것이 중요함
    • 행렬을 나타내기 위해서는 리스트를 사용할 수도 있지만, 행렬 연산이 직관적이지 않고 오류 가능성이 높기 때문에, 행렬 연산을 위해서는 numpy 사용이 필수이다.
import numpy as np

#리스트로 행렬 표현
a = [[1,0], [0,1]]
b = [[1,1], [1,1]]

a+b
👩‍💻결과
[[1, 0], [0, 1], [1, 1], [1, 1]]
#numpy matrix, 직관적임
a = np.array([[1,0], [0,1]])
b = np.array([[1,1], [1,1]])

a+b
👩‍💻결과
array([[2, 1],
       [1, 2]])

2. vector(벡터)

  • vector는 np.array([...])를 사용하여 생성함
  • 머신러닝 코드 구현시, 연산을 위해서 vector, matrix 등의 형상(shape), 차원(dimension)을 확인하는 것이 필요함
a = np.array([1,2,3])
b = np.array([4,5,6])

#vector a,b 출력
print(a,b)

#vector a,b 형상출력 -> shape
print("a.shape=",a.shape, "b.shape=",b.shape)

#vector a,b 차원출력 -> ndim
print("a.ndim=",a.ndim,"b.ndim=",b.ndim)
👩‍💻결과
[1 2 3] [4 5 6]
a.shape= (3,) b.shape= (3,)
a.ndim= 1 b.ndim= 1

3. matrix(행렬)

  • vector와 마찬가지로 np.array([[...],[...],...])를 사용하여 생성함
a = np.array([[1,2,3],[4,5,6]])
b = np.array([[-1,-2,-3],[-4,-5,-6]])

#matrix a,b 형상출력 -> shape
print("a.shape=",a.shape, "b.shape=",b.shape)

#matrix a,b 차원출력 -> ndim
print("a.ndim=",a.ndim,"b.ndim=",b.ndim)
👩‍💻결과
a.shape= (2, 3) b.shape= (2, 3)
a.ndim= 2 b.ndim= 2
  • 형변환(reshape)
    - vector를 matrix로 변경하거나 matrix를 다른 형상의 matrix로 변경하기 위해서는 reshape() 사용하여 행렬의 shape을 변경하여야 함.
c = np.array([1,2,3])

#vector c 형상출력 -> shape
print("c.shape=",c.shape)

#vector를 (1,3)행렬로 형변환
c = c.reshape(1,3)

#vector c 형상출력 -> shape
print("c.shape=",c.shape)
👩‍💻결과
c.shape= (3,)
c.shape= (1, 3)

4. dot product(행렬곱)

  • np.dot()
  • 행렬 a의 열 벡터와 행렬 b의 행 벡터가 크기가 같아야 한다. 만약 같지 않다면 reshape 또는 전치행렬 등을 사용하여 형 변환을 한 후에 행렬 곱 실행해야 함
a = np.array([[1,2,3],[4,5,6]]) #2*3
b = np.array([[-1,-2],[-3,-4],[-5,-6]]) #3*2

#(2*3) dot product(3*2) = (2*2)
c = np.dot(a,b) # 행렬 곱 수행

print("a=", a)
print("b=", b)
print("a.shape=",a.shape,"b.shape=",b.shape)
print("c.shape=",c.shape)
print("c=",c)
👩‍💻결과
a= [[1 2 3]
 [4 5 6]]
b= [[-1 -2]
 [-3 -4]
 [-5 -6]]
a.shape= (2, 3) b.shape= (3, 2)
c.shape= (2, 2)
c= [[-22 -28]
 [-49 -64]]
 

5. broadcast(브로드캐스트)

  • 행렬의 사칙연산은 기본적으로 두 개의 행렬 크기가 같은 경우에만 수행할 수 있다.
  • 그러나 numpy에서는 크기가 다른 두 행렬간에도 사칙연산을 할 수 있는 브로드캐스트가 있다.
  • 차원이 작은 쪽이 큰 쪽의 행 단위로 반복적으로 크기를 맞춘 후에 계산
a = np.array([[1,2],[3,4]])
b = 5

a+b
👩‍💻결과
array([[6, 7],
       [8, 9]])
c = np.array([[1,2],[3,4]])
d = np.array([4,5])

c+d
👩‍💻결과
array([[5, 7],
       [7, 9]])

6. transpose(전치행렬)

  • 원본 행렬의 열은 행으로, 행은 열로 바꾼 것으로서, 원본 행렬을 a라고 하면 전치행렬은 a^T로 나타냄
  • 즉, 1행은 1열로 바꾸고 2행은 2열로...
a = np.array([[1,2],[3,4],[5,6]]) #3*2
b= a.T #a의 전치행렬, 2*3

print("a.shape=",a.shape, "b.shape=",b.shape)
print("a=",a)
print("b=",b)
👩‍💻결과
a.shape= (3, 2) b.shape= (2, 3)
a= [[1 2]
 [3 4]
 [5 6]]
b= [[1 3 5]
 [2 4 6]]
 
c = np.array([1,2,3,4,5]) #vector(matrix 아님)
d = c.T # c는 vector이므로 transpose 안됨

e = c.reshape(1,5) #1*5 matrix
f = e.T #e의 전치행렬

print("c.shape=",c.shape, "d.shape=",d.shape)
print("e.shape=",e.shape, "f.shape=",f.shape)
print("d=",d)
print("f=",f)
👩‍💻결과
c.shape= (5,) d.shape= (5,)
e.shape= (1, 5) f.shape= (5, 1)
d= [1 2 3 4 5]
f= [[1]
   [2]
   [3]
   [4]
   [5]]

7. 행렬 원소 접근 - indexing, slicing, iterator

  • indexing, slicing
  • iterator
    - 행렬 모든 원소를 access 하는 경우에는 iterator 사용가능
    • numpy iterator는 c++, java iterator 처럼 next() 메서드를 통해 데이터 값을 처음부터 끝까지 순차적으로 읽어 들이는 방법을 제공
  • https://numpy.org/doc/stable/reference/generated/numpy.nditer.html

    iterable이란?
    member를 하나씩 반환할 수 있는 object를 말합니다.
    iterable의 예로는 sequence type인 list, str, tuple이 있습니다.

a = np.array([[10,20,30,40], [50,60,70,80]])

print("a =>",a,"\n")
print("a.shape =>",a.shape, "\n")

it = np.nditer(a, flags=['multi_index'], op_flags=['readwrite'])
#multi_index는 다중 인덱스 또는 반복 차원 당 하나의 인덱스 튜플이 추적되도록합니다.
#readwrite는 피연산자가 읽고 쓸 것임을 나타냅니다.

while not it.finished: #피연산자에 대한 반복이 완료되었는지 여부입니다.
    idx = it.multi_index
    print("idx =>", idx)
    print("current value ->", a[idx])
    it.iternext() #원소끝까지 이동할 수 있다.
👩‍💻결과
a => [[10 20 30 40]
 [50 60 70 80]] 
a.shape => (2, 4) 

idx => (0, 0)
current value -> 10
idx => (0, 1)
current value -> 20
idx => (0, 2)
current value -> 30
idx => (0, 3)
current value -> 40
idx => (1, 0)
current value -> 50
idx => (1, 1)
current value -> 60
idx => (1, 2)
  current value -> 70
  idx => (1, 3)
  current value -> 80

8. concatenate

  • 행렬에 행 또는 열 추가하기 위한 numpy.concatenate(..)
  • 머신러닝의 회귀 코드 구현 시, 가중치와 바이어스를 별도로 구분하지 않고 하나의 행렬로 취급하기 위한 프로그래밍 구현 기술
a = np.array([[10,20,30], [40,50,60]])
print(a.shape)

# a matrix에 행 추가할 행렬, 1행 3열로 reshape
# 행을 추가하기 때문에 우선 열을 3열로 만들어야 함
row_add = np.array([70,80,90]).reshape(1,3) #vector -> matrix

#a matrix에 열 추가할 행렬, 2행 1열로 생성
#열을 추가하기 때문에 우선 행을 2행으로 만들어야 함.
column_add = np.array([1000,2000]).reshape(2,1)

#numpy.concatenate 에서 axis = 0 행(row) 기준
#a 행렬에 row_add 행렬 추가
b = np.concatenate((a, row_add), axis=0)
print(b)

#numpy.concatenate 에서 axis = 1 열(column) 기준
#b 행렬에 column_add 행렬 추가
c = np.concatenate((a, column_add),axis=1)
print(c)
👩‍💻결과
(2, 3)
[[10 20 30]
 [40 50 60]
 [70 80 90]]
[[  10   20   30 1000]
 [  40   50   60 2000]]

9. loadtxt

  • seperator로 구분된 파일에서 데이터를 읽기 위한 numpy.loadtxt(...)
  • 머신러닝 코드에서 입력데이터와 정답데이터를 분리하는 프로그래밍 기법
  • 예시
    - 콤마(,)로 분리된 데이터 파일을 read 하기 위해서는 np.loadtxt() 사용
    - 리턴값은 행렬이기 때문에 인덱싱 또는 슬라이싱을 이용하여 데이터를 분리 할 필요가 있다.

    np.loadtxt('경로', delimiter=',', dtype=np.float32)

10. numpy.random.rand(...)

  • 0~1 사이의 random number 발생
  • 가중치나 바이어스에 임의의 값을 넣을 때 사용

11. numpy.sum, numpy.exp, numpy.log

  • numpy.sum : 합
  • numpy.exp : np.exp() 함수는 밑(base)이 자연상수 e 인 지수함수로 변환해줍니다.
  • numpy.log : 지수함수의 역함수인 로그함수는 밑이 자연상수 e, 혹은 10, 또는 2 이냐에 따라서 np.log(x), np.log10(x), np.log2(x) 를 구분해서 사용합니다.

12. numpy.max, numpy.min, numpy.argmax, numpy.argmin

  • numpy.max : vector에서 최대값 리턴 / matrix에서는 행(axis=1) 또는 열(axis=0) 기준으로 구한다.
  • numpy.min : vector에서 최소값 리턴 / matrix에서는 행(axis=1) 또는 열(axis=0) 기준으로 구한다.
  • numpy.argmax : vector에서 최대값이 있는 인덱스 리턴 / matrix에서는 행(axis=1) 또는 열(axis=0) 기준으로 구한다.
  • numpy.argmin : vector에서 최소값이 있는 인덱스 리턴 / matrix에서는 행(axis=1) 또는 열(axis=0) 기준으로 구한다.
profile
Sin prisa, sin pausa.

0개의 댓글