티스토리 뷰

do/Bigdata & A.I

Numpy

dooo.park 2019. 10. 4. 14:03

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
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함