8. 파이썬 Advanced

Data Analytics에서 파이썬은 상당히 유용한 패키지들을 많이 제공한다.

지금부터 파이썬과 함께 쓰면 유용한 패키지들에 대해서 알아본다.

앞으로 진행하게 될 텐서플로우도 마찬가지다.

이번 장에서 살펴 볼 패키지들은 텐서플로우를 사용하면서도 많이 활용될 것이다.


NUMPY

Numerical Python의 줄임말로 다차원 배열인 ndarray(N-dimensional array)와 선형대수, 난수 발생 등의 수학적 계산에 많이 사용된다.

파이썬의 리스트 자료구조는 다양한 자료형을 저장할 수 있어 매유 유연하지만 메모리 점유 공간이 많고 속도가 느려지고, 프로그램 오류를 발생시키는 경우가 많다.

이러한 문제를 해결하기 위해 numpy의 ndarray를 사용한다.


numpy의 ndarray 사용하기

import numpy as np

a = [1, 2, 3, 4, 5, 6]
npa = np.array(a)
print(type(a))
print(type(npa))
print(npa.dtype)

b = [1.0, 2.0, 3.0, 4.0, 5.0]
npb = np.array(b)
print(npb.dtype)

print(npa[0])
npa[0] = 10
print(a)

npc = np.array([[1, 2], [3, 4]])
print(npc[0, 0], npc[0, 1])

실행결과

<class 'list'>
<class 'numpy.ndarray'>
int32
float64
1
[1, 2, 3, 4, 5, 6]
1 2

numpy의 ndarray는 리스트를 사용하는 방법과 유사하게 사용할 수 있다.


많이 쓰이는 함수

import numpy as np

print(np.zeros(5))
print(np.zeros((3, 3)))
print(np.ones(5))
print(np.random.rand(2, 2))

실행결과

[ 0.  0.  0.  0.  0.]
[[ 0.  0.  0.]
 [ 0.  0.  0.]
 [ 0.  0.  0.]]
[ 1.  1.  1.  1.  1.]
[[ 0.58613583  0.20208349]
 [ 0.85597352  0.49402706]]
  • zeros(): 0으로 초기화된 배열을 만든다.
  • ones(): 1로 초기화된 배열을 만든다.
  • random.rand(): 랜덤값으로 초기화화된 배열을 만든다.


arange()와 linespace()

import numpy as np

a = np.arange(10)
b = np.arange(3, 10, 2)
c = np.linspace(0, 2, 5)

print(a)
print(b)
print(c)

실행결과

[0 1 2 3 4 5 6 7 8 9]
[3 5 7 9]
[ 0.   0.5  1.   1.5  2. ]

파이썬의 rang()는 빌트인 함수로 리스트를 반환하고 arange()함수는 배열을 반환한다는 점이 다르다.

linespace()함수는 일정한 구역을 등간격으로 배열을 생성한다.


arrary.shape & array.dtype

import numpy as np

npArr1 = np.array([1, 2, 3, 4, 5, 6])
print(npArr1.shape)
print(npArr1.dtype)

npArr2 = np.array([[1, 2], [3, 4], [5, 6]])
print(npArr2.shape)

npArr3 = np.array([[[1], [2], [3]], [[4], [5], [6]]])
print(npArr3.shape)

실행결과

(6,)
int32
(3, 2)
(2, 3, 1)

npArr1은 1차원만 가지고 있고, 6개의 값을 가지고 있다는 뜻이고, npArr2는 1차원에 3개의 값, 2차원에 2개의 값을 가지고 있다는 뜻이다.

npArr3은 1차원에 2개, 2차원에 3개, 3차원에 1개의 값을 가지고 있다는 내용을 나타낸다.


reshape()

import numpy as np

array1 = np.arange(6)
print(array1)

array2 = np.arange(6).reshape(2, 3)
print(array2)

array3 = np.arange(12).reshape(2, 2, 3)
print(array3)

실행결과

[0 1 2 3 4 5]
[[0 1 2]
 [3 4 5]]
[[[ 0  1  2]
  [ 3  4  5]]
 [[ 6  7  8]
  [ 9 10 11]]]

reshape()함수는 배열의 차원을 변경할 수 있는 함수이다.


ndarray의 연산

import numpy as np

data1 = np.array([1, 2, 3, 4, 5])
data2 = np.array([10, 20, 30, 40, 50])

print(data1 * 10)
print(data1 * data2)

print(data1 + 2)
print(data1 + data2)

print(data1 ** 2)

실행결과

[10 20 30 40 50]
[ 10  40  90 160 250]
[3 4 5 6 7]
[11 22 33 44 55]
[ 1  4  9 16 25]

nparray끼리의 사칙연산은 각 항목끼리 이뤄진다. 빌트인 자료형인 리스트와는 다르게 연산되는 점에 주목할 필요가 있다.


브로드캐스팅(broadcasting)

import numpy as np

x = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
print(x.shape)

v = np.array([10, 20, 30])
print(v.shape)

y = x + v
print(y)

실행결과

(4, 3)
(3,)
[[11 22 33]
 [14 25 36]
 [17 28 39]
 [20 31 42]]

브로드캐스팅은 numpy에서 shape이 다른 배열사이에서 산술 연산이 가능하게 해주는 기능이다.

브로드캐스팅 규칙은 다음과 같다.

행렬A와 벡터V의 연산에서 벡터V의 크기가 행렬A의 행또는 열과 동일한 경우

  • m*n 행렬과 m*1 벡터 간의 연산
  • m*n 행령과 1*n 벡터 간의 연산

열벡터와 행벡터간의 연산

  • m*1 벡터와 1*n 벡터 간의 연산

이러한 경우 한 쪽의 크기가 다른 쪽의 크기로 확장된 후 요소간 연산을 수행한다.

즉, 비교 대상인 두 개의 차원이 서로 같은 값이거나, 2개 중에 1개가 1이라면 두 개의 차원이 동일하다고 간주한다

그리고, 연산 결과 배열의 차원은 최대 크기가 된다.

import numpy as np

a = np.arange(12).reshape(4, 3)
print(a)

b = np.array([0, 1, 2])
print(b)

print(a + b)

b = np.array([0, 1, 2, 3]).reshape(4, 1)
print(b)
print(a + b)

실행결과

[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]]
[0 1 2]
[[ 0  2  4]
 [ 3  5  7]
 [ 6  8 10]
 [ 9 11 13]]
[[0]
 [1]
 [2]
 [3]]
[[ 0  1  2]
 [ 4  5  6]
 [ 8  9 10]
 [12 13 14]]


sum()

import numpy as np

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

print(np.sum(x))
print(np.sum(x, axis=0))
print(np.sum(x, axis=1))

실행결과

10
[4 6]
[3 7]


ndarray의 슬라이싱

import numpy as np

a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
print(a)

b = a[:2, 1:3]
print(b)

print(a[0, 1])
b[0, 0] = 20
print(a[0, 1])

실행결과

[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
[[2 3]
 [6 7]]
2
20

이러한 numpy에서의 슬라이싱은 텐서플로우에서 빈번하게 사용된다.


MATPLOTLIB

matplotlib는 그래프를 그려주는 파이썬의 시각화 라이브러리이다.


직선 그리기

import matplotlib.pyplot as plt

x = range(10)
y = range(10)

plt.plot(x, y)
plt.show()

실행결과


그래프 꾸미기

import matplotlib.pyplot as plt

x = range(10)
y = range(10)

plt.plot(x, y, label="y=x")
plt.title("example")
plt.xlabel("X axis")
plt.ylabel("Y axis")
plt.legend()
plt.show()

실행결과

산포도 그래프

import matplotlib.pyplot as plt
import numpy as np

x = np.random.rand(100)
y = np.random.rand(100)

plt.scatter(x, y)
plt.title("example")
plt.xlabel("X axis")
plt.ylabel("Y axis")
plt.show()

실행결과

imshow() 함수

import matplotlib.pyplot as plt
import numpy as np

a = [1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0]
np1 = np.array(a)
plt.imshow(np1.reshape(4, 4), cmap='Greys', interpolation='nearest')
plt.show()

실행결과

imshow() 함수는 배열의 데이터를 이미지로 렌더링하는 함수입니다.