티스토리 뷰
Numpy란?
NumPy는 행렬이나 일반적으로 대규모 다차원 배열을 쉽게 처리 할 수 있도록 지원하는 파이썬의 라이브러리이다.
NumPy는 데이터 구조 외에도 수치 계산을 위해 효율적으로 구현된 기능을 제공한다.
Numpy 설치
$ pip install numpy
1. Numpy 사용준비
python 파일에 Numpy를 import 시킨다. 보통 np로 사용
import numpy as np
2. Numpy 배열
- 벡터 : 1차원 배열
- 매트릭스 : 2차원 배열
3. 배열 생성 방법
1. 파이썬 리스트 이용 : np.array([list])
# 1차원 배열 = 벡터
list = [1,2,3,4,5]
type(list)
>list
arr = np.array(list)
type(arr)
> numpy.ndarray
# 2차원 배열 = 매트릭스
mat = [[1,2],[3,4]]
mat
> [[1, 2], [3, 4]]
m_arr = np.array(mat)
m_arr
> array([[1, 2],
[3, 4]])
2. 0또는 1로 채우기 : np.zeros(), np.ones()
# 모든 요소가 0 값을 가지는 배열 생성
np.zeros(5)
np.zeros((5,5))
> array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]])
# 모든 요소가 1 값을 가지는 배열 생성
np.ones(5)
np.ones((5,5))
> array([[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.]])
3. 일정한 간격을 가지는 숫자 배열: np.arange()
# 0부터 10까지, 간격 1을 가지는 배열
np.arange(0, 11)
> array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
# 0부터 10까지, 간격 2를 가지는 배열
np.arange(0, 11, 2)
> array([ 0, 2, 4, 6, 8, 10])
4. 일정 범위 안에서 일정 갯수를 가진 배열: np.linspace()
5. 랜덤 값을 가지는 배열: np.random.rand() / np.random.randn() / np.random.randint()
# 0과 1범위 내의 연속 균등 분포(uniform)에서 랜덤으로 값을 가져와 생성
np.random.rand(5)
np.random.rand(5,5)
> array([[0.12254621, 0.92884386, 0.58126172, 0.60185882, 0.64536204],
[0.3295713 , 0.93572354, 0.11733849, 0.79929562, 0.75672396],
[0.89817067, 0.79925751, 0.84008219, 0.2537302 , 0.01268672],
[0.95441844, 0.89355971, 0.9190382 , 0.42935171, 0.20285285],
[0.16995644, 0.19143037, 0.63081986, 0.03197892, 0.5192281 ]])
# 0과 1범위 내의 정규 분포(standard normal)에서 랜덤으로 값을 가져와 생성
np.random.randn(5)
np.random.randn(5,5)
> array([[ 1.21875811, -0.59179127, 0.98932486, 0.06366124, 0.76152327],
[ 0.54375271, -0.31188142, 2.14254591, -0.55516233, -0.62034551],
[ 1.83388107, -0.89992732, 1.30849774, 0.65300983, 0.64999143],
[-2.59104014, 0.29814667, 0.21671847, -0.96318646, -0.14224246],
[ 0.09672846, -0.0458007 , 1.39403336, 0.26667342, 0.09385206]])
> # 특정 범위 내에서 랜덤 정수형 숫자(int)를 가져와 생성
np.random.randint(1,1000)
np.random.randint(1,1000, 5)
> array([715, 331, 330, 3, 689])
4. 배열 요소 접근 및 범위 선택
1. 배열 요소 접근 방식은 파이썬 리스트와 동일
2. 범위 접근자(:) 사용 시 범위에 주의 (1:5 는 1부터 4까지)
3. 배열 복사(메모리 문제 방지): XXX.copy()
4. 특정 조건에 해당하는 데이터 선택은 인덱스를 사용
arr = np.array([[1,3,5], [7,9,11], [2,4,6], [8,10,12]])
arr
> array([[ 1, 3, 5],
[ 7, 9, 11],
[ 2, 4, 6],
[ 8, 10, 12]])
arr[1]
> array([ 7, 9, 11])
arr[ : ,2]
> array([ 5, 11, 6, 12])
arr[1:3,0:2]
> array([[7, 9],
[2, 4]])
arr_cpy = arr.copy()
arr_cpy
> array([[ 1, 3, 5],
[ 7, 9, 11],
[ 2, 4, 6],
[ 8, 10, 12]])
5. 배열 다루기
1. 배열 모양 확인: XXX.shape()
2. 배열 내의 데이터 자료형 확인: XXX.dtype
3. 배열 모양 변경: XXX.reshape()
4. 데이터 타입 변경: XXX.astype()
arr = np.array([[1,2,3],[4,5,6]])
arr.shape
> (2, 3)
arr.dtype
> dtype('int64')
arr.reshape(3,2)
> array([[1, 2],
[3, 4],
[5, 6]])
(arr.astype(float)).dtype
> dtype('float64')
배열 쪼개기 / 합치기
# arr1 = 5x5 array
# arr2 = 3x1 array
# arr3 = 3x1 array
arr1 = np.array([[1,2],[3,4],[5,6],[7,8],[9,10]])
arr2 = np.zeros(3)
arr3 = np.ones(2)
print(arr1)
print(arr2)
print(arr3)
arr1.shape, arr2.shape, arr3.shape
> [[ 1 2]
[ 3 4]
[ 5 6]
[ 7 8]
[ 9 10]]
> [0. 0. 0.]
> [1. 1.]
> ((5, 2), (3,), (2,))
2 * arr3
> array([2., 2.])
np.concatenate()
# row 기준으로 합치기
con = np.concatenate((arr2, arr3), axis=0)
con.shape
> (5,)
# col 기준으로 합치기
rst = np.concatenate((arr1, con), axis=1)
rst.shape
> (5, 3)
# col을 기준으로 합치려면 reshape이 필요
print(arr1.shape)
print(con.shape)
con = con.reshape(5,1)
con, con.shape
> (5, 2)
> (5, 1)
> (array([[0.],
[0.],
[0.],
[1.],
[1.]]), (5, 1))
# col 기준으로 합치기
rst = np.concatenate((arr1, con), axis=1)
rst, rst.shape
> (array([[ 1., 2., 0.],
[ 3., 4., 0.],
[ 5., 6., 0.],
[ 7., 8., 1.],
[ 9., 10., 1.]]), (5, 3))
조건에 따른 데이터
rst > 0
> array([[ True, True, False],
[ True, True, False],
[ True, True, False],
[ True, True, True],
[ True, True, True]])
rst[:, rst[2]>0]
> array([[ 1., 2.],
[ 3., 4.],
[ 5., 6.],
[ 7., 8.],
[ 9., 10.]])
# 특정 col 잘라내기: 방금 추가한 con 열을 제거
col_del = rst[:,0:2]
col_del
> array([[ 1., 2.],
[ 3., 4.],
[ 5., 6.],
[ 7., 8.],
[ 9., 10.]])
# 특정 row 잘라내기: 첫 번째: 제일 첫번째 row를 제거
row_del = rst[1:, :]
row_del
> array([[ 3., 4., 0.],
[ 5., 6., 0.],
[ 7., 8., 1.],
[ 9., 10., 1.]])
# 특정 조건에 부합하는 col 잘라내기: 3 번째 col이 0인 row
rst[rst[:,2]==0, :]
> array([[1., 2., 0.],
[3., 4., 0.],
[5., 6., 0.]])
rst
> array([[ 1., 2., 0.],
[ 3., 4., 0.],
[ 5., 6., 0.],
[ 7., 8., 1.],
[ 9., 10., 1.]])
a = np.array([[ 0, 1, 2, 0, 4, 5, 6, 7, 8, 9],
[ 0, 11, 0, 13, 0, 15, 0, 17, 18, 0]])
print(a.shape)
a[:,a[1]!=0]
> (2, 10)
> array([[ 1, 0, 5, 7, 8],
[11, 13, 15, 17, 18]])
numpy 슬라이싱
numpy 배열은 파이썬 리스트와 마찬가지로 슬라이스(Slice)를 지원한다.
numpy 배열을 슬라이싱하기 위해서는 각 차원별로 슬라이스 범위를 지정한다.
import numpy as np
lst = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
arr = np.array(lst)
# 슬라이스
a = arr[0:2, 0:2]
print(a)
# 출력:
# [[1 2]
# [4 5]]
a = arr[1:, 1:]
print(a)
# 출력:
# [[5 6]
# [8 9]]
numpy 정수 인덱싱 (integer indexing)
numpy 슬라이싱이 각 배열 차원별 최소-최대의 범위를 정하여 부분 집합을 구하는 것이라면,
정수 인덱싱은 각 차원별로 선택되어지는 배열요소의 인덱스들을 일렬로 나열하여 부분집합을 구하는 방식이다.
즉, 임의의 numpy 배열 a 에 대해 a[[row1, row2], [col1, col2]] 와 같이 표현하는 것인데, 이는 a[row1, col1] 과 a[row2, col2] 라는 두 개의 배열요소의 집합을 의미한다.
예를 들어, 아래 예제에서 a[[0, 2], [1, 3]] 은 정수 인덱싱으로서 이는 a[0, 1] 과 a[2, 3] 등 2개의 배열요소를 가리킨다.
import numpy as np
lst = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
]
a = np.array(lst)
# 정수 인덱싱
s = a[[0, 2], [1, 3]]
print(s)
# 출력
# [2 12]
numpy 부울린 인덱싱 (boolean indexing)
numpy 부울린 인덱싱은 배열 각 요소의 선택여부를 True, False로 표현하는 방식이다.
만약 배열 a 가 2 x 3 의 배열이이라면, 부울린 인덱싱을 정의하는 numpy 배열도 2 x 3 으로 만들고 선택할 배열요소에 True를 넣고 그렇지 않으면 False를 넣으면 된다.
예를 들어, 아래 예제에서 3 x 3 배열 a 중 짝수만 뽑아내는 부울린 인덱싱 배열(numpy 배열)을 사용하여 짝수 배열 n 을 만드는 예이다.
import numpy as np
lst = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
a = np.array(lst)
bool_indexing_array = np.array([
[False, True, False],
[True, False, True],
[False, True, False]
])
n = a[bool_indexing_array];
print(n)
부울린 인덱싱 배열에 True/False 값을 일일이 지정하는 방법 이외에 표현식을 사용하여 부울린 인덱싱 배열을 생성하는 방법이 있다.
예를 들어, 배열 a 에 대해 짝수인 배열요소만 True로 만들고 싶다면, bool_indexing = (a % 2 == 0) 와 같이 표현할 수 있다.
아래 예제는 이러한 표현을 사용하는 것을 예시한 것이고, 특히 마지막에 a[ a % 2 == 0 ] 와 같이 부울린 인덱싱 표현식을 배열 인덱스안에 넣어 간단하게 표현할 수도 있다.
import numpy as np
lst = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
a = np.array(lst)
# 배열 a 에 대해 짝수면 True, 홀수면 False
bool_indexing = (a % 2 == 0)
print(bool_indexing)
# 출력: 부울린 인덱싱 배열
# [[False True False]
# [ True False True]
# [False True False]]
# 부울린 인덱스를 사용하여 True인 요소만 뽑아냄
print(a[bool_indexing])
# 출력:
# [2 4 6 8]
# 더 간단한 표현
n = a[ a % 2 == 0 ]
print(n)
numpy 연산
numpy를 사용하면 배열간 연산을 쉽게 실행할 수 있다.
연산은 +, -, *, / 등의 연산자를 사용할 수도 있고, add(), substract(), multiply(), divide() 등의 함수를 사용할 수도 있다.
예를 들어, 아래 예제와 같이 배열 a 와 b 가 있을때, a + b를 하면 각 배열요소의 합을 구하는데 즉 a[0]+b[0], a[1]+b[1], ... 과 같은 방식으로 결과를 리턴하게 된다.
import numpy as np
a = np.array([1,2,3])
b = np.array([4,5,6])
# 각 요소 더하기
c = a + b
# c = np.add(a, b)
print(c) # [5 7 9]
# 각 요소 빼기
c = a - b
# c = np.subtract(a, b)
print(c) # [-3 -3 -3]
# 각 요소 곱하기
# c = a * b
c = np.multiply(a, b)
print(c) # [4 10 18]
# 각 요소 나누기
# c = a / b
c = np.divide(a, b)
print(c)
# [0.25 0.4 0.5]
numpy에서 vector와 matrix의 product를 구하기 위해서 dot() 함수를 사용한다.
아래 예제는 두 matrix의 product를 구한 예이다.
import numpy as np
lst1 = [
[1,2],
[3,4]
]
lst2 = [
[5,6],
[7,8]
]
a = np.array(lst1)
b = np.array(lst2)
c = np.dot(a, b)
print(c)
# 출력:
# [[19 22]
# [43 50]]
numpy은 배열간 연산을 위한 위해 많은 함수들을 제공하는데, 예를 들어, 각 배열 요소들을 더하는 sum() 함수, 각 배열 요소들을 곱하는 prod() 함수 등을 사용할 수 있다.
이들 함수에 선택옵션으로 axis 을 지정할 수 있는데, 예를 들어 sum()에서 axis가 1 이면 행끼리 더하는 것이고, axis가 0 이면 열끼리 더하는 것이다.
import numpy as np
a = np.array([[1,2],[3,4]])
s = np.sum(a)
print(s) # 10
# axis=0 이면, 컬럼끼리 더함
# axis=1 이면, 행끼리 더함
s = np.sum(a, axis=0)
print(s) # [4 6]
s = np.sum(a, axis=1)
print(s) # [3 7]
s = np.prod(a)
print(s) # 24
참고사이트 : http://pythonstudy.xyz/python/article/402-numpy-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0
'do > Bigdata & A.I' 카테고리의 다른 글
Pandas (0) | 2019.10.07 |
---|