파이썬 준비
프로그램 설치
아나콘다 : 다양한 수치계산, 머신러닝용 외부 패키지가 내장된 파이썬 모듈
-> https://www.anaconda.com/download#Windows
주피터 노트북 : 머신러닝 IDE. 아나콘다에 내장되어있으며 웹페이지 형식으로 작업함
-> Anaconda3 > Anaconda Navigator > Jupyter Notebook Launch
주피터 노트북 파일생성 : 대시보드의 New > Python 3 을 선택하면 .jpynb확장자 파일을 생성할 수 있다.
명령 실행 단축키 : Shift + Enter
노트북 쉘은 파이썬 쉘과 같이 한번 모듈을 import해두면 명령 실행 후에도 사용할 수 있고, 변수도 마찬가지로 계속 사용할 수 있다.
주피터 노트북 종료 : 노트북 서버에서 하나의 프로세스로 실행되기 때문에 브라우저를 닫는다 해도 프로세스는 종료되지 않는다. File > Close and Halt 버튼을 클릭하거나 대시보드의 러닝탭에서 shutdown하여 주피터를 종료해줘야 한다.
파이썬 문법
자료형 확인
a = 1313
print(type(a))
-> <class 'int'>
한행에 여러 명령어
a = True; b = False; print(a+b)
연산자
+ - * /
// : 나눗셈 후 몫만 가져오기
% : 나눗셈 후 나머지만 가져오기
** : 거듭제곱
<, >, <=, >=, ==, !=
and, or, not
in : 포함여부
ex) y=['a', 'b', 'x', 'c']
'x' in y; -> true
리스트 []
>>> a = [1, 2, 3] + [4, 5, 6]
>>> print(a)
[1, 2, 3, 4, 5, 6]
>>> L = [i*i for i in range(10)] # for문의 반환값으로 i*i를 계산해서 리스트의 데이터로 넣어준다.
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# [원소에대한처리 for 원소 in 리스트 if 조건문]
>>> a = [1, 2, 3, 4, 5, 6, 7]
>>> b = [c*2 for c in a if c < 5] # a의 원소들 중 c에 대해 5 미만인 경우 c*2해서 b의 원소로 넣는다
>>> print(b)
[2, 4, 6, 8]
>>> c = [1, 2, 3]
>>> c1, c2, c3 = c
>>> print(c1, c2, c3)
10 11 12
>>> c.append(5)
>>> print(c)
[1, 2, 3, 5]
튜플 ()
리스트와 마찬가지로 여러개의 값을 다룰때 사용하는데, 튜플은 원소 추가, 삭제, 변경이 불가능하다.
>>> a = (1, 2, 3, 4, 5) ; b = a[2]
>>> print(a + (6, 7, 8, 9)) # +연산자로 새로운 튜플을 만들어 낼 수 있다
(1, 2, 3, 4, 5, 6, 7, 8, 9)
>>> c = (10, 11, 12)
>>> c1, c2, c3 = c
>>> print(c1, c2, c3)
10 11 12
딕셔너리 {}
키와 값 쌍을 데이터로 갖는 자료형
>>> a = {"Apple" : 3, "Pineapple" : 4}
>>> a["Pineapple"] = 6 # 딕셔너리 값 변경
>>> print(a["Pineapple"])
6
>>> a["Melon"] = 99 # 딕셔너리에 값 추가
>>> print(a)
{'Apple': 3, 'Pineapple': 4, 'Melon': 99}
조건문
if a <12 :
반복문
for a in [4, 7, 10]:
for a in range(3):
while a < 3:
함수
>>> def add(a, b=5): # 기본값을 설정한 함수
return a+b
>>> print(add(3))
>>> def add(a, b, c):
print(a+b+c)
>>> e = (1, 2, 3)
>>> add(*e) # 튜플에 *를 붙여 함수안의 인자로 전달할 수 있다.
>>> a = 123
>>> def setGlobal():
global a # 함수 내에서 글로벌변수 a를 선언
a = 456
>>> setGlobal()
>>> print(a)
456
클래스
파이썬도 객체지향 프로그래밍이 가능하다.
클래스 : 설계도, 틀 / 인스턴스 : 실체
>>> class Calc:
def __init__(self, a): # 생성자. 인스턴스의 초기값 설정
self.a = a # 인스턴스별로 할당된 인스턴스 변수 a에 인자로받은 a를 넣는다.
def add(self, b):
print(self.a + b) # a는 인스턴스화 되어 같은 인스턴스의 메소드인 add에서도 사용할 수 있다.
def multiply(self, b):
print(self.a * b)
>>> calc = Calc(3) # Calc 클래스의 인스턴스 생성 (a=3 calc인스턴스에서만 유지됨)
>>> calc.add(4) # add 메소드 실행(3+4)
>>> calc.multiply(5) # multiply 메소드 실행 (3*5)
>>> class CalcPlus(Calc): # Calc 클래스를 상속받음
def substract(self, b):
print(self.a - b)
def devide(self, b):
print(self.a / b)
>>> calc_plus = CalcPlus(5) # CalcPlus 클래스 인스턴스 생성
>>> calc_plus.add(4) # 상속받아서 Calc의 메소드를 사용할 수 있음. (5+4)
>>> calc_plus.devide(10) # CalcPlus의 메소드 (5/10)
넘파이 모듈
수학함수 라이브러리를 내장하는 파이썬모듈. 다차원 배열을 지원하면서 내부는 C로 작성되어 실행속도가 빠르다.
import numpy as np # 넘파이 모듈에 별명을 지정해줘서 np라는 이름으로 다룰 수 있게 된다.
배열 생성
>>> a = np.array([0, 1, 2, 3, 4, 5]) # 1차원
>>> print(a)
[0 1 2 3 4 5]
>>> b = np.array([[0,1,2], [3,4,5]]) # 2차원
>>> print(b)
[[0 1 2]
[3 4 5]]
>>> c = np.array([[[0,1,2], [3,4,5]], [[6,7,8], [9,0,1]]]) # 3차원
>>> print(c)
[[[0 1 2]
[3 4 5]]
[[6 7 8]
[9 0 1]]]
>>> print(np.zeros(10)) # 0으로 이뤄진 길이 10의 배열 생성 후 출력
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] # 0. 인 이유는 부동소수점 실수임을 표현
>>> g = np.ones(10); g # 1로 이뤄진 길이 10의 배열 생성 후 변수 g에 저장
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
>>> g[2]
1.0
>>> print(np.random.rand(4)) # 0~1 사이의 랜덤한 값으로 이뤄진 배열 생성
[0.07750046 0.91623676 0.54525929 0.22444675]
>>> print(np.zeros((2,3))) # 길이를 튜플로 전달해서 다차원 배열을 생성할 수 있다.
[[0. 0. 0. ]
[0. 0. 0. ]]
>>> print(np.arange(0, 1, 0.1)) # 0~1 사이에서 0.1 간격으로 배열 원소 생성
[0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]
# 시작하는 수의 default는 0, 간격의 defualt는 1이다
>>> print(np.linspace(0, 1, 4)) # 0~1 범위의 총 4개의 원소를 갖는 배열 생성
[0. 0.33 0.66 1. ]
# 원소 수의 default는 50
배열 형태 변환
>>> c = np.array([[[0,1,2], [3,4,5]], [[6,7,8], [9,0,1]]])
>>> print(np.shape(c)) # 배열의 모양
(2, 2, 3) # (뒤에서부터 읽음)가로3 세로2 높이2 인 3차원배열
>>> print(np.size(c)) # 배열의 총 원소 수
12
>>> d = [[1,2], [3,4], [5,6]] # (3,2) 형태
>>> print(len(d)) # 배열의 원소 개수를 가져온다 (= 가장높은 차원의 원소개수)
3
>>> print(np.array(d))
[[1 2]
[3 4]
[5 6]]
>>> print(len(np.array(d))) # d를 np array형태로 변경 후 길이를 센다.
3
>>> a = np.array([0, 1, 2, 3, 4, 5, 6, 7]) # 원소 8개의 배열 생성
>>> b = a.reshape(2, 4) # 배열 a를 (2, 4) 형태로 변경. 당연히 다차원 -> 다차원도 가능하다.
>>> print(b)
[[0 1 2 3]
[4 5 6 7]]
>>> b = np.reshape(a, (2, 4)) # 위와 동일
>>> c = b.reshape(-1) # -1을 인자로 전달하는경우 자동으로 계산해달라는 의미이다.
>>> print(c)
[0, 1, 2, 3, 4, 5, 6, 7]
>>> c = b.reshape(2, -1) # 세로 2만 맞추고 나머지는 원소 개수에 따라 자동으로 맞춘다.
배열 연산
파이썬 자체적으로는 에러가 발생한다.
>>> a = np.array([0, 1, 2, 3, 4, 5]).reshape(2, 3)
>>> print(a * 3) # 각 원소에 3을 곱함
[[ 0 3 6]
[ 9 12 15]]
>>> b = np.array([2, 3, 4, 5, 4, 3])
>>> c = np.array([2, 4, 5]) # (3,)
>>> print(a * b)
# 에러발생
>>> print(a * c)
[[ 0 4 10] # 0*2 1*4 2*5
[ 6 16 25]] # 3*2 4*4 5*5
>>> c = np.array([[2], [3]]) # (2, 1)
[[ 0 2 4] # 0*2 1*2 2*2
[ 9 12 15]] # 3*3 4*3 5*3
# 서로 같은 차원의 원소 수가 같으면서 원소 수가 대응이 되어야 한다 (브로드캐스트 규칙)
배열 원소에 접근
>>> a = np.array([[0, 1, 2], [3, 4, 5]])
>>> print(a[1, 2]) # 2차원, 1차원 순서. a[1][2]와 같다.
5
>>> print(a[1]) # 인덱스를 하나만 지정하는 경우 가장 높은차원을 지정하는것이다.
[3, 4, 5]
>>> b = np.array([1,2,3,4,5,6,7,8,9]).reshape(3,3)
>>> b[1] = np.array([10, 11, 12]) # 배열 인덱스 위치에 배열을 삽입
>>> print(b)
[[ 0 1 2]
[10 11 12]
[ 7 8 9]]
>>> c = np.array([1,2,3,4,5,6,7,8,9])
>>> print(c[c%2 == 0]) # 배열의 인덱스가 조건에 맞는 경우에만 가져옴
[1 3 5 7 9] # 0, 2, 4, 6, 8 인덱스의 값을 가져옴
>>> e = np.zeros((3, 3)) # 원소값이 0인 3*3 배열
>>> f = np.array([8, 9]) # 저장될 값
>>> e[np.array([0,2]), np.array([0,1])] = f # [8의x축 9의x축, 8의y축 9의y축]
>>> print(e)
[[8. 0. 0.]
[0. 0. 0.]
[0. 9. 0.]]
# 원래는 [x, y]에 형식인데 배열로 되어있기 때문에 [[x1 x2], [y1 y2]] 순서로 위치를 잡는다.
# 정확히 따지면 [2차, 1차]
배열 슬라이싱
>>> a = np.array([0,1,2,3,4,5,6,7,8,9])
>>> print(a[3:5])
[3 4]
>>> print(a[2:8:2]) # [시작:끝:간격] 파이썬은 끝 -1 까지만 한다
[2 4 6]
>>> print(a[:]) # 모든 원소
[0 1 2 3 4 5 6 7 8 9]
>>> b = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
>>> b[0:2, 0:2] = np.array([9,9], [0,0]) # 각 차원의 범위를 지정하고 값을 변경
>>> print(b)
[[9, 9, 2],
[0, 0, 5],
[6, 7, 8]]
>>> c = np.zeros(18).reshape(2, 3, 3)
>>> c[0, 1:3, 1:3] = np.ones(4).reshape(2,2) # 3차원 배열도 가능하다
[[[0. 0. 0.]
[0. 1. 1.]
[0. 1. 1.]]
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]]
배열 축
배열을 선언할 때의 순서와 같다. 가장 고차원을 왼쪽부터 적듯 고차원이 0번 인덱스를 가지고 있다.
쉽게 생각하면 np.shape(a) 함수 반환값(2, 3) 인덱스의 차원(0: 2차원, 1: 1차원)으로 보면 된다.
축변경 함수 transpose
>>> a = np.array([[0, 1, 2], [3, 4, 5]])
>>> print(a.transpose(1, 0) # print(a.T)와 같다.
[[0 3]
[1 4]
[2 5]]
>>> a = np.arange(0, 18).reshape(2,3,3)
>>> print(a)
[[[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8]],
[[ 9, 10, 11],
[12, 13, 14],
[15, 16, 17]]]
>>> print(a.T) # a.transpose(2,1,0) 과 같다.
[[[ 0, 9],
[ 3, 12],
[ 6, 15]],
[[ 1, 10],
[ 4, 13],
[ 7, 16]],
[[ 2, 11],
[ 5, 14],
[ 8, 17]]]
a.transpose(2,1,0)
transpose 함수를 사용하게 되면 기본 축(0,1,2)으로 정렬되어 있던 배열이 함수로 전달한 인자(2,1,0)에 맞춰 기존 축 axis=2(1차원)가 0(3차원)의 위치로, 1->1, 0->2의 축으로 변경된다.
축이 변경됨에 따라 데이터가 쌓이는 순서가 변경되었다고 보면 된다.
변경되기 전에는 1차원이 [ [[1 2 3], ...] ...] 이렇게 쌓였지만 축이 1->3차원축으로 변경됨에 따라 [ [[1..], ..], [[2..], ..] ..] 이렇게 쌓인다.
함수
>>> a = np.array([[0, 1], [2, 3]])
>>> print(np.sum(a))
6
# 모든 원소의 합을 계산해준다.
>>> print(np.sum(a, axis=0))
[2 4]
# 1차원축을 모양대로(세로방향) 더해준다.
>>> print(np.sum(a, axis=1, keepdims=True))
[[1]
[5]]
# 2차원축 모양대로 (가로방향) 더해주고 차원을 유지한다.(keepdims)
>>> print(np.max(a)) # 원소중 가장큰값 출력
3
>>> print(np.argmax(a, axis=0)) # 세로방향(axis=0)에서 가장 큰값의 인덱스
[1 1]
# np.where(조건, 조건을 만족하는값, 조건을 만족하지않는값)
>>> print(np.where(a<2, 9, a)) # a의 인자중 2보다 작은값은 9로 변경하고 아니면 a 그대로 둔다.
[[9 9]
[2 3]]
맷플롯립
넘파이같은 파이썬 외부 모듈로 그래프나 이미지 표시, 간단한 애니메이션 생성등이 가능하다.
%matplotlib inline # 맷플롯립의 그래프를 인라인으로 표시하기 위해 선언
import numpy as np
import matplotlib.pyplot as plt
그래프 생성
0~2파이까지 sin함수 그래프를 생성
>>> x = np.linspace(0, 2*np.pi) # 0~2파이까지 x축
>>> y_sin = np.sin(x) # sin(x) 그래프의 결과값을 y에 담기
>>> y_cos = np.cos(x) # cos(x) 그래프의 결과값을 y에 담기
>>> plt.xlabel("x value") # 축이름 지정
>>> plt.ylabel("y value")
>>> plt.title("sin/cos") # 그래프 이름 지정
>>> plt.plot(x, y_sin, label="sin") # sin으로 라벨 지정
>>> plt.plot(x, y_cos, label="cos", linestyle="dashed") # cos로 라벨 지정, 선 스타일 대쉬형태
>>> plt.legend() # 범례를 label과 자동으로 연결. 파라미터로 따로 지정 가능
>>> plt.show()
*** 나중에 그림첨부하기
산포도 표시
>>> x_1 = np.random.rand(100) - 1.0
>>> x_2 = np.random.rand(100)
>>> y_1 = np.random.rand(100)
>>> y_2 = np.random.rand(100)
>>> plt.scatter(x_1, y_1, marker="+") # 위에서 x_1 에서 1을 뺐기 때문에 왼쪽으로 1만큼 이동한다.
>>> plt.scatter(x_2, y_2, marker="*")
>>> plt.show()
*** 나중에 그림첨부하기
이미지 표시
>>> img = np.arange(16).reshape(4,4) # 4*4 배열 생성 숫자는 0~15까지
>>> plt.imshow(img, "gray") # 그레이스케일로 표시
>>> plt.colorbar() # 컬러막대 표시
>>> plt.show()
# 배열을 이미지로 표시
>>> img = plt.imread("flower.png")
>>> plt.imshow(img)
>>> plt.show()
# 이미지를 불러올 수 있다.
*** 나중에 그림첨부하기
'프로젝트 > 게임 AI' 카테고리의 다른 글
인공지능을 위한 수학 : 로그의 유래 (0) | 2019.08.07 |
---|---|
인공지능을 위한 수학 level 1 : 변수와 상수 ~ 자연로그 (0) | 2019.08.06 |
딥러닝 선수지식 3 : 수학과 파이썬 (0) | 2019.08.05 |
딥러닝 선수지식 1 : 딥러닝이란? (0) | 2019.08.03 |