2018년 9월 8일 토요일

파이썬 Numpy 수학 라이브러리

파이썬 Numpy 수학 라이브러리

파이썬 라이브러리

참고 자료 : Scipy Lecture Notes

matplotlib 을 이용하여 그래프 그리기

맷플롯립 패키지를 불러오고, 그래프를 노트북 문서 안에 나타낼 수 있도록 설정한다

In [1]:
import matplotlib.pyplot as plt
%matplotlib inline 

리스트 데이터를 그래프로 나타내기

In [2]:
x = [0,1,2,3]
y = [0,1,4,10]
plt.plot( x, y )
plt.show()

numpy 라이브러리

numpy 를 이용하여 함수를 그래프로 그리기

numpy 라이브러리를 불러온다.

In [3]:
import numpy as np

numpy 를 이용하여 $x$ 데이터에 대한 리스트를 만들고, $y= \cos \left( 2x \right)$ 를 그린다.

In [4]:
x = np.linspace( -np.pi, np.pi, 101)    # 100 steps between -pi and pi 
y = np.cos( 2*x )                       # numpy가 제공하는 수학 함수
plt.plot( x, y )
plt.show()

다중 그래프 그리기

In [5]:
x = np.linspace(-np.pi,np.pi,101)    # 100 steps between -pi and pi
y = np.cos( 2*x )
z = np.exp( -x**2 )

fig = plt.figure()
axes = fig.add_subplot(1,2,1)
axes.plot( x, y )

axes2 = fig.add_subplot(1,2,2)
axes2.plot( x, z )
plt.show()

[참고] np. 을 생략하려면 numpy 라이브러리를 통째로 도입한다.

일반적인 math 라이브러리와 혼동될 수 있으므로 주의하여야 한다.

In [6]:
from numpy import *

x = linspace( -pi, pi, 101)          # 100 steps between -pi and pi 
y = cos( 2*x )                       # numpy가 제공하는 수학 함수
plt.plot( x, y )
plt.show()

배열 만들기

np.array() 함수

In [7]:
import numpy as np

a = np.array([0, 1, 2, 3, 4])
a
Out[7]:
array([0, 1, 2, 3, 4])

파이썬의 리스트 데이터형 보다 더 효율적이다.

배열의 차원과 원소의 갯수

In [8]:
a.ndim
Out[8]:
1
In [9]:
len(a)
Out[9]:
5

2차원 배열

In [10]:
b = np.array([[0, 1, 2], [3, 4, 5]])
b
Out[10]:
array([[0, 1, 2],
       [3, 4, 5]])

배열의 차원과 원소의 갯수

In [11]:
b.ndim  
Out[11]:
2
In [12]:
len(b)       # 첫번째 차원의 크기 (행의 갯수)를 반환한다.
Out[12]:
2

행과 열의 갯수

In [13]:
b.shape
Out[13]:
(2, 3)

np.arange() 함수

In [14]:
np.arange(10)
Out[14]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

복수 인자: 시작, 끝, 간격

In [15]:
np.arange(1, 9, 2)         # 끝은 포함하지 않는다.
Out[15]:
array([1, 3, 5, 7])

실수 범위를 일정 간격으로 나누는 경우에 유용하다.

In [16]:
np.arange(1, 2, 0.2)       # 끝은 포함하지 않는다.
Out[16]:
array([1. , 1.2, 1.4, 1.6, 1.8])

끝점을 포함하고 싶다면, 다음과 같은 트릭을 쓸 수도 있다.

In [17]:
np.arange(1, 2.0001, 0.2)      
Out[17]:
array([1. , 1.2, 1.4, 1.6, 1.8, 2. ])

np.linspace() 함수

시작, 끝, 점의 갯수

In [18]:
a = np.linspace(0, 1, 6)
a
Out[18]:
array([0. , 0.2, 0.4, 0.6, 0.8, 1. ])

같은 간격으로 끝점을 포함하지 않으려면, 점의 갯수를 하나 줄이고 endpoint=False 로 설정한다.

In [19]:
a = np.linspace(0, 1, 5, endpoint=False)
a
Out[19]:
array([0. , 0.2, 0.4, 0.6, 0.8])
In [20]:
a = np.linspace(0, 1, 5, endpoint=True)
a
Out[20]:
array([0.  , 0.25, 0.5 , 0.75, 1.  ])

여러가지 행렬

단위 행렬

In [21]:
a = np.eye(3)
a
Out[21]:
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])

영 행렬

In [22]:
b = np.zeros((2, 2))
b
Out[22]:
array([[0., 0.],
       [0., 0.]])

원소가 1인 행렬

In [23]:
c = np.ones((2, 3))
c
Out[23]:
array([[1., 1., 1.],
       [1., 1., 1.]])

1차원 벡터를 대각 행렬로 만들기

In [24]:
d = np.diag(np.array([1, 2, 3, 4]))
d
Out[24]:
array([[1, 0, 0, 0],
       [0, 2, 0, 0],
       [0, 0, 3, 0],
       [0, 0, 0, 4]])

다른 데이타 형식의 배열

복소수 배열

In [25]:
d = np.array([1+2j, 3+4j, 5+6*1j])
d
Out[25]:
array([1.+2.j, 3.+4.j, 5.+6.j])

난수 발생

In [26]:
a = np.random.rand(4)          # 0 과 1 사이의 균등한 분포
a
Out[26]:
array([0.00457864, 0.05477524, 0.5127786 , 0.48834374])

가우스 분포

In [27]:
b = np.random.randn(4)         # Gaussian
b
Out[27]:
array([ 0.14260759, -0.87042911, -0.19687729,  1.47004801])

난수 발생기의 초기화

In [28]:
np.random.seed(1234)          # Setting the random seed

초기화에 필요한 정수를 만들려면, time 모듈을 사용하면 편리하다.

In [29]:
import time
time.time()       # 1970년 1월 1일 0시 0분 0초를 기준으로 현재까지 지나간 시간을 초 단위로 리턴
Out[29]:
1544335829.5357673
In [30]:
np.random.seed( int(time.time()) )          # Setting the random seed

인덱싱과 슬라이싱

파이썬의 리스트와 같은 방식이 적용된다.

In [31]:
a = np.arange(10)
a
Out[31]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

인덱싱

In [32]:
a[0], a[2], a[-1]
Out[32]:
(0, 2, 9)

슬라이싱

마지막 인덱스는 포함되지 않는다.

In [33]:
a[1:3]
Out[33]:
array([1, 2])

시작의 디폴트 값은 0 이다.

In [34]:
a[:4]
Out[34]:
array([0, 1, 2, 3])

시작:끝:간격 조건을 명시하는 경우

In [35]:
a[2:9:3]           # [ 시작:끝:간격 ]
Out[35]:
array([2, 5, 8])

원소를 역순으로 배치하려면

In [36]:
a[::-1]            # 원소를 역순으로 배치
Out[36]:
array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])

다차원 배열의 인덱싱

In [37]:
a = np.diag(np.arange(3))
a
Out[37]:
array([[0, 0, 0],
       [0, 1, 0],
       [0, 0, 2]])
In [38]:
a[1, 1]
Out[38]:
1
In [39]:
a[2, 1] = 10            # third row, second column
a
Out[39]:
array([[ 0,  0,  0],
       [ 0,  1,  0],
       [ 0, 10,  2]])
In [40]:
a[1]                   # second row
Out[40]:
array([0, 1, 0])

배열의 수치적 연산

원소별 연산

스칼라와의 연산

In [41]:
a = np.array([1, 2, 3, 4])
a
Out[41]:
array([1, 2, 3, 4])
In [42]:
a + 1
Out[42]:
array([2, 3, 4, 5])
In [43]:
2**a
Out[43]:
array([ 2,  4,  8, 16], dtype=int32)

배열 사이의 연산은 해당 원소 끼리의 연산이다.

In [44]:
b = np.ones(4) + 1
b
Out[44]:
array([2., 2., 2., 2.])
In [45]:
a - b
Out[45]:
array([-1.,  0.,  1.,  2.])

이차원 배열의 곱셈은 행렬 곱셈이 아니다.

In [46]:
a * b                 # 같은 위치의 원소 끼리의 곱셈이다
Out[46]:
array([2., 4., 6., 8.])
In [47]:
c = np.ones((3, 3))
c
Out[47]:
array([[1., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.]])
In [48]:
c * c                 # 같은 위치의 원소 끼리의 곱셈이다
Out[48]:
array([[1., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.]])

행렬 곱셈은 dot() 을 사용한다.

In [49]:
c.dot(c)                    # 행렬 곱셈
Out[49]:
array([[3., 3., 3.],
       [3., 3., 3.],
       [3., 3., 3.]])

행렬의 곱셈 : np.dot( A, B )

In [50]:
np.dot( c, c )              # 행렬 곱셈
Out[50]:
array([[3., 3., 3.],
       [3., 3., 3.],
       [3., 3., 3.]])

배열의 비교

같은 위치에 있는 원소들을 서로 비교한다.

In [51]:
a = np.array([1, 2, 3, 4])
b = np.array([4, 2, 2, 4])
a == b
Out[51]:
array([False,  True, False,  True])
In [52]:
a > b
Out[52]:
array([False, False,  True, False])

배열을 통째로 비교하려면

In [53]:
a = np.array([1, 2, 3, 4])
b = np.array([4, 2, 2, 4])
c = np.array([1, 2, 3, 4])

np.array_equal(a, b)
Out[53]:
False
In [54]:
np.array_equal(a, c)         
Out[54]:
True

모든 원소들이 같은 경우에만 참이다

배열의 논리 연산

In [55]:
a = np.array([1, 1, 0, 0], dtype=bool)
a
Out[55]:
array([ True,  True, False, False])
In [56]:
b = np.array([1, 0, 1, 0], dtype=bool)
b
Out[56]:
array([ True, False,  True, False])
In [57]:
np.logical_or(a, b)
Out[57]:
array([ True,  True,  True, False])
In [58]:
np.logical_and(a, b)
Out[58]:
array([ True, False, False, False])

배열의 초월 함수

In [59]:
x = np.linspace(-np.pi,np.pi,13)         # 12 steps between -pi and pi
x
Out[59]:
array([-3.14159265, -2.61799388, -2.0943951 , -1.57079633, -1.04719755,
       -0.52359878,  0.        ,  0.52359878,  1.04719755,  1.57079633,
        2.0943951 ,  2.61799388,  3.14159265])
In [60]:
np.sin(x)
Out[60]:
array([-1.22464680e-16, -5.00000000e-01, -8.66025404e-01, -1.00000000e+00,
       -8.66025404e-01, -5.00000000e-01,  0.00000000e+00,  5.00000000e-01,
        8.66025404e-01,  1.00000000e+00,  8.66025404e-01,  5.00000000e-01,
        1.22464680e-16])
In [61]:
x = np.arange(5)
x
Out[61]:
array([0, 1, 2, 3, 4])
In [62]:
np.log(x)
C:\ProgramData\Anaconda3\lib\site-packages\ipykernel_launcher.py:1: RuntimeWarning: divide by zero encountered in log
  """Entry point for launching an IPython kernel.
Out[62]:
array([      -inf, 0.        , 0.69314718, 1.09861229, 1.38629436])
In [63]:
np.exp(x)
Out[63]:
array([ 1.        ,  2.71828183,  7.3890561 , 20.08553692, 54.59815003])

원소들의 합

In [64]:
x = np.array([1, 2, 3, 4])

np.sum(x)
Out[64]:
10

또는

In [65]:
x.sum()
Out[65]:
10

최대값, 최소값

In [66]:
x = np.array([1, 3, 2])

x.max()
Out[66]:
3
In [67]:
x.min()
Out[67]:
1

최대값, 최소값의 인덱스

In [68]:
x.argmax()         #최대값의 인덱스
Out[68]:
1
In [69]:
x.argmin()         #최소값의 인덱스
Out[69]:
0

논리 연산

In [70]:
np.all([True, True, False])
Out[70]:
False
In [71]:
np.any([True, True, False])
Out[71]:
True

[예] 같은 위치에 있는 모든 원소에 대하여, a 보다 b 가 같거나 크고, b 보다 c 가 같거나 큰가를 확인한다.

In [72]:
a = np.array([1, 2, 3, 2])
b = np.array([2, 2, 3, 2])
c = np.array([6, 4, 4, 5])
In [73]:
((a <= b) & (b <= c)).all()
Out[73]:
True

통계

In [74]:
x = np.array([1, 1, 2, 3, 5])
x.mean()
Out[74]:
2.4
In [75]:
np.median(x)              # 가운데에 위치한 값
Out[75]:
2.0
In [76]:
x.std()                  # 표준편차
Out[76]:
1.4966629547095764

Numeric Analysis 4 - Numeric Linear Algebra

Numeric Analysis 4 - Numeric Linear Algebra Numeric Linear Algebra ¶ ...