In [1]:
import matplotlib.pyplot as plt
import numpy as np
In [2]:
%matplotlib inline
실전 문제를 넘파이 모율을 이용하여 해결하는 두 가지 예제를 살펴본다. 넘파이 모듈을 사용하면 이전에 복잡하게 했던 일을 훨씬 간단하게, 그리고 빠르게 처리할 수 있음에 주의해야 한다.
여기서는 아래 함수 또는 방법들의 활용을 배운다.
np.linspace()
np.loadtxt()
먼저 x축의 구간을 정한다.
예를 들어, [0, 3]
의 구간으로 하자.
이제 그 구간을 균등하게 쪼개어 x축 상에서 30개의 x좌표를 구해 보자.
In [3]:
xs = np.linspace(0, 3, 30)
xs
Out[3]:
이제 y = 3 * x
함수를 정의하자.
In [4]:
def times_3(x):
return 3*x
이제 y축 상에 x좌표에 해당하는 30개의 y좌표를 구할 수 있다.
힌트: 넘파이 모듈에서 함수에 어레이를 인자로 사용하면, 함수는 각각의 항목을 인자로 사용하여 새로운 어레이를 생성하여 리턴한다.
In [5]:
ys = times_3(xs)
ys
Out[5]:
주의: ys
는 아래와 같이 정의할 수도 있다.
In [6]:
ys = 3 * xs
ys
Out[6]:
3 * xs
는 xs
의 각각의 항목에 3을 곱한다. 이와 같이 어레이의 연산은 각각의 항목에 대해 실행된다.
이제 xs
와 ys
를 이용하여 times_3
함수의 그래프를 다음과 같이 그릴 수 있다.
In [7]:
plt.plot(xs, ys)
Out[7]:
plt.plot
함수에 세번 째 인자를 옵션으로 사용하여 그래프 모양을 변경할 수 있다.
예를 들어, 'o' 옵션은 점으로 좌표를 찍으라는 것을 나타낸다.
In [8]:
plt.plot(xs, ys, 'o')
Out[8]:
두 경우를 합쳐서 그래프를 그려서 그래프가 어떻게 그려졌는지 쉽게 확인할 수도 있다.
In [9]:
plt.plot(xs, ys)
plt.plot(xs, ys, 'o')
Out[9]:
이번에는 x
좌표값의 구간을 [-1, 1]
로 정한 후, 그 구간에서 균등하게 20개의 x좌표값을 구하자.
In [10]:
xs = np.linspace(-1, 1, 20)
xs
Out[10]:
이제 숫자를 제곱해서 리턴하는 함수를 정의한다.
In [11]:
def square(x):
return x**2
이제 x좌표값들에 대응하는 y좌표값들을 구하자.
In [12]:
ys = square(xs)
ys
Out[12]:
주의: ys
를 아래와 같이 선언할 수 있다.
In [13]:
ys ** 2
ys
Out[13]:
이제 각각 xs
와 ys
로 이루어진 x좌표값 y좌표값들을 이용하여 제곱함수의 그래프를 그려보자.
In [14]:
plt.plot(xs, ys)
plt.plot(xs, ys, 'o')
Out[14]:
먼저 아래 사이트에서 populations.txt 파일을 다운 받는다. 파일을 다운 받으려면 링크에 마우스를 가져간 다음 마우스 오른쪽 버튼을 눌러 링크에 연결된 파일을 다운받으면 된다.
https://github.com/scipy-lectures/scipy-lecture-notes/blob/master/data/populations.txt
해당 파일은 1900년부터 1920년까지 캐나다 북부지역에서 서식한 산토끼(hare)와 스라소니(lynx)의 숫자, 그리고 채소인 당근(carrot)의 재배숫자를 순수 텍스트 데이터로 담고 있다.
파일의 내용은 아래와 같다.
주의: 아래 코드는 파이썬 코드가 아님에 주의할 것.
In [15]:
!cat data/populations.txt
# !type populations.txt
앞서 설명한 대로 각 연도별로 산토끼, 스라소니, 당근의 개체수를 담고 있다.
이제 해당 파일을 파이썬으로 불러 들이자.
여기서는 파이썬의 open
함수 대신에 numpy
의 loadtxt
함수를 이용한다.
In [16]:
data = np.loadtxt('data/populations.txt')
data
를 확인해 보면 주석처리, 즉, 무시 해야 할 첫째 행을 제외한 나머지가
2차원 어레이로 저장되었음을 확인할 수 있다.
In [17]:
data
Out[17]:
1900년부터 1920년까지, 즉, 21년 동안 산토끼, 스라소니, 당근의 개체수를 조사한 데이터이다.
따라서 위 데이터는 21 x 4
모양의 2차원 행렬에 해당한다.
실제로 위 데이터의 모양(shape)를 확인하면 동일한 결과를 얻는다.
In [18]:
data.shape
Out[18]:
이제 위 데이터를 이용하여 1900년부터 1920년 사이에 각 개체별로 어떤 변화가 발생하였는지를 분석하고자 한다. 분석을 위해서는 그래프를 이용하는 것이 가장 효율적이다.
각 개체별 개체수의 21년간의 데이터를 먼저 구해야 한다. 그러기 위해 전치(transposition) 함수를 이용한다.
data.T
주의: 전치함수는 행과 열을 서로 바꾼다.
In [19]:
data.T
Out[19]:
즉, data.T
는 4 x 21
모양의 2차원 어레이이며,
각각의 행은 차례대로 년도, 산토끼 수, 스라소니 수, 당근 수를 연도별로 담고 있다.
각각의 행을 독립된 어레이로 추출해야 하는데, 넘파이는 각각의 행에 대해 변수를 선언할 수 있는 기능을 제공한다.
주의: 튜플의 경우 각각의 항목에 변수를 선언할 수 있는 것과 동일하다.
In [20]:
year, hares, lynxes, carrots = data.T
예를 들어 year
변수에는 연도들로 이루어진 1차원 어레이가 할당된다.
In [21]:
year
Out[21]:
hares
변수에는 각 연도별 개체수로 이루어진 1차원 어레이가 할당된다.
In [22]:
hares
Out[22]:
lynxes
, carrots
경우도 동일하게 작동한다.
아래 그림은 연도별 산토끼의 개체수, 스라소니의 개체수, 당근의 재배수를 각각 파란색, 녹색, 빨간색 그래프를 이용하여 동시에 표현한 것이다.
plot
, axes
, legned
함수의 활용방법에 대해서는 우선 너무 많은
신경을 쓰지 않아도 된다. 여기서는 기본 사용법만 알면 된다.
plot
함수: 여러 개의 선 그래프를 동시에 그릴 수 있다.
axes
함수: 셋째, 넷째 인자는 그래프의 크기를 결정한다.
반면에 첫째, 둘째 인자는 그래프의 위치를 지정할 때 사용한다.
하지만 plot
함수 등 그래프를 그리는 함수가 한 번만 호출된 경우에는 별 의미가 없다.
legend
함수: 범례를 추가하며, loc
키워드 인자는 범례의 위치를 지정한다.
In [23]:
plt.axes([0.2, 0.1, 0.5, 0.8])
plt.plot(year, hares, year, lynxes, year, carrots)
plt.legend(('Hare', 'Lynx', 'Carrot'), loc=(1.05, 0.5))
Out[23]: