[밑딥] 1장. 헬로 파이썬

Speedwell🍀·2022년 4월 7일
0

이번 챕터에서는 파이썬, 넘파이 matplotlib에 대한 내용을 다룬다.
파이썬 부분은 건너뛰도록 하겠다!!

1. Numpy

  • 배열/행렬 계산
  • 넘파이의 배열 클래스인 numpy.array에는 편리한 메서드가 많아 딥러닝 구현할 때 많이 이용!

넘파이 배열 생성

np.array()
: 파이썬의 리스트를 인수로 받아 넘파이 라이브러리가 제공하는 특수한 형태의 배열(numpy.ndarray)을 반환한다.

>>> x = np.array([1.0, 2.0, 3.0])
>>> print(x)
[1. 2. 3.]
>>> type(x)
<class 'numpy.ndarray'>

넘파이 산술 연산

>>> x = np.array([1.0, 2.0, 3.0])
>>> y = np.array([2.0, 4.0, 6.0])
>>> x + y # 원소별(element-wise) 덧셈
array([3., 6., 9.])
>>> x - y 
array([-1., -2., -3.])
>>> x * y # elsement-wise product
array([2., 8., 18.])
>>> x / y 
array([0.5, 0.5, 0.5])

📌 배열 x와 y의 원소 수가 같아야 한다!

넘파이 배열은 원소별 계산뿐 아니라 넘파이 배열과 수치 하나(스칼라값)의 조합으로 된 산술 연산도 수행 가능!
➡️ 브로드캐스트 (아래에서 자세히 다루자)


넘파이의 N차원 배열

2차원 배열(행렬)을 작성해보자.

>>> A = np.array([[1, 2], [3, 4]]) # 2x2 행렬
>>> print(A)
[[1 2]
 [3 4]]
>>> A.shape # 행렬의 형상
(2, 2)
>>> A.dtype # 행렬에 담긴 원소의 자료형 
dtype('int64')

>>> B = np.array([[3, 0], [0, 6]]) 
>>> A + B
array([[ 4, 2],
 	   [ 3, 10])
>>> A * B
array([ 3, 0],
	  [ 0, 24]])
>>> A * 10
array([[ 10, 20]
	   [ 30, 40]])

형상: 행렬을 포함한 N차원 배열에서 그 배열의 '각 차원의 크기(원소의 수)' ➡️ shape으로 알 수 있다.
행렬에 담긴 원소형은 dtype으로 알 수 있다.

벡터(vector): 1차원 배열
행렬(matrix): 2차원 배열
텐서(tensor): 벡터와 행렬을 일반화한 것
이 책에서는 2차원 배열을 행렬, 3차원 이상의 배열을 다차원 배열이라고 한다.


브로드캐스트 (broadcast)

넘파이에서는 형상이 다른 배열끼리도 계산할 수 있다. ➡️ 브로드캐스트

>>> x = np.array([1.0, 2.0, 3.0])
>>> x / 2.0
array([0.5, 1., 1.5])
>>> A = np.array([[1, 2], [3, 4]])
>>> B = np.array([10, 20])
>>> A * B
array([[ 10, 40],
	   [ 30, 80]])

원소 접근

인덱스로 원소 접근

>>> X = np.array([[51, 55], [14, 19], [0, 4]])
>>> print(X)
[[51 55]
 [14 19]
 [ 0  4]]
>>> X[0] 
array([51, 55])
>>> X[0][1]
55

for문으로 원소 접근

>>> for row in X:
		print(row)

[51 55]
[14 19]
[0 4]

인덱스를 배열로 지정해 한 번에 여러 원소에 접근

>>> X = X.flatten()  # X를 1차원 배열로 변환(평탄화)
>>> print(X)
[51 55 14 19  0  4]
>>> X[np.array([0, 2, 4])] # 인덱스가 0, 2, 4인 원소 얻기
array([51, 14,  0])

특정 조건을 만족하는 원소에만 접근

>>> X > 15
array([ True,  True, False,  True, False, False], dtype=bool)
>>> X[X>15]
array([51, 55, 19])

📌 넘파이의 주된 처리는 C와 C++로 구현!
이유) 파이썬 같은 동적 언어는 C나 C++같은 정적 언어(컴파일 언어)보다 처리 속도가 늦다. 그래서 무거운 작업을 할 때는 C/C++로 작성한 프로그램을 쓰는 편이 좋다.
➡️ 파이썬에서 빠른 성능이 요구될 경우, 해당 부분을 C/C++로 구현한다. (이때 파이썬은 C/C++로 쓰인 프로그램을 호출해주는 중개자 같은 역할)


2. matplotlib

: 그래프 그리기, 데이터 시각화를 위한 라이브러리!

단순한 그래프 그리기

📌 그래프를 그리려면 matplotlib의 pyplot 모듈을 이용한다.

sin 함수를 그려보자!

import numpy as np
import matplotlib.pyplot as plt

# 데이터 준비
x = np.arange(0, 6, 0.1) # 0에서 6까지 0.1 간격으로 생성
y = np.sin(x)

# 그래프 그리기
plt.plot(x, y)
plt.show()

코드 설명

  1. 넘파이의 arange 메서드로 [0, 0.1, 0.2, ..., 5.8, 5.9]라는 데이터를 생성하여 변수 x에 할당했다.
  2. x의 각 원소에 넘파이의 sin 함수인 np.sin()을 적용하여 변수 y에 할당한다.
  3. x와 y를 인수로 plt.plot 메서드를 호출해 그래프를 그린다.
  4. 마지막으로 plt.show()를 호출해 그래프를 화면에 출력한다.

추가) np.arange() vs range()

참고사이트

  1. 표현 단위

    • np.arange는 실수 단위도 표현 가능
    • range 함수는 정수 단위만 표현 가능

  1. 자료형 반환
    • np.arange는 numpy array 자료형 반환
      ➡️ 넘파이에서 수행하는 연산 연계가 가능
    • range는 range iterator 자료형 반환

  1. 수행시간 차이

    • np.arange는 입출력에서 range보다 약 3배 더 많은 시간 소요

      • 하지만 array에서 직접 연산하는 경우는 np.arange가 압도적으로 유리
    • range는 for 문 등에서 순회하고 싶은 수열이 정수로 구성되어 있을 때 유리


pyplot의 기능

위의 sin 함수에서 cos 함수도 추가적으로 그려보자!
pyplot에서 제공하는 제목각 축의 이름(레이블) 표시 등의 기능도 사용해보자!

import numpy as np
import matplotlib.pyplot as plt

# 데이터 준비
x = np.arange(0, 6, 0.1) # 0에서 6까지 0.1 간격으로 생성
y1 = np.sin(x)
y2 = np.cos(x)

# 그래프 그리기
plt.plot(x, y1, label="sin")
plt.plot(x, y2, linestyle="--", label="cos") # cos 함수는 점선으로 그리기
plt.xlabel("x") # x축 이름
plt.ylabel("y") # y축 이름
plt.title('sin & cos') # 제목
plt.legend()
plt.show()

추가) plt.legend()

참고사이트

legend(범례): 그래프에 데이터의 종류를 표시하기 위한 텍스트

📌사용 방법:
plot() 함수에 label 문자열을 지정하고 legend() 함수를 호출한다.


위에서 구현한 sin & cos 그래프에서 plt.legend()를 사용하면 아래와 같다.


이미지 표시하기

📌 imshow() : pyplot에서 이미지를 표시해주는 메서드

import matplotlib.pyplot as plt
from matplotlib.image import imread

img = imread('lena.png') # 이미지 읽어오기 (경로 설정 해야 함)

plt.imshow(img)
plt.show()

책에서 추천하는 참고 자료

책 추천

파이썬

  • 처음 시작하는 파이썬 (한빛미디어, 2015)

넘파이

  • 파이썬 라이브러리를 활용한 데이터 분석 (한빛미디어, 2013)

사이트 추천

넘파이 & matplotlib

  • <Spicy 강의 노트>

0개의 댓글