본문 바로가기
데이터 어쩌구/전처리 및 시각화

[객체지향] Numpy

by annmunju 2022. 1. 6.

 

 

[라이브러리] import numpy as np

1. Numpy? NumPy("넘파이"라 읽는다)는 행렬이나 일반적으로 대규모 다차원 배열을 쉽게 처리 할 수 있도록 지원하는 파이썬의 라이브러리이다. NumPy는 데이터 구조 외에도 수치 계산을 위해 효율적

mungdo-log.tistory.com

[배열(array) 기초]

1) array 생성 : array(object, dtype, ...)

data = [1,2,3]
arr = np.array(data)
arr

# array([1, 2, 3])

 

2) array 크기 확인 : shape

arr.shape

# (3,)

 

3) array 자료형 확인 : dtype

arr.dtype

# dtype('int64')

- 부호가 있는 정수 int(8, 16, 32, 64)
- 부호가 없는 정수 uint(8, 16, 32, 64)
- 실수 float(16, 32, 64, 128)
- 복소수 complex(64, 128, 256)
- 불리언 bool
- 문자열 string_
- 파이썬 오브젝트 object
- 유니코드 unicode_

 

4) 데이터 타입 변환 : astype()

(1) 문자열 배열을 숫자형 배열로 변환

data1 = ['1', '2', '1.5', '3.14']
data2 = ['1', '2', '4', '3']

str_a1 = np.array(data1)
# >> array(['1', '2', '1.5', '3.14'], dtype='<U4')
num_a1 = str_a1.astype(float)
# >> array([1.  , 2.  , 1.5 , 3.14]) : 가장 긴 자리수에 맞춰 저장됨
# str_a2 = np.array(data1).astype(int) : ValueError (float 포함)
str_a2 = np.array(data2).astype(int)

(2) 실수형 배열을 정수형 배열로 변환

data3 = [10, 21, 0.549, 4.75, 5.98]

num_f1 = np.array(data3)
num_i1 = num_f1.astype(int)

num_i1 # array([10, 21,  0,  4,  5])

(3) 숫자형 배열을 문자열 배열로 변환

num_f1.astype('U')
# array(['10.0', '21.0', '0.549', '4.75', '5.98'], dtype='<U32')

num_i1.astype('a') # num_i1.astype('S')
# array([b'10', b'21', b'0', b'4', b'5'], dtype='|S21')

 


 

[배열 생성의 다양한 방법]

1) np.arange() 함수 : np.arange([start,] stop[, step])

np.arange(10) # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
np.arange(5,1,-1) # array([5, 4, 3, 2])

* 형태를 변경하는 함수 : reshape(n, m)

- reshape 크기가 안맞으면 불가능! np.arange(x).reshape(n,m) ... x = n*m

np.arange(12).reshape(3,4)
# array([[ 0,  1,  2,  3],
#        [ 4,  5,  6,  7],
#        [ 8,  9, 10, 11]])

 

2) np.linspace() 함수 : np.linspace(start, stop[, num=50])

np.linspace(1,10,10)
# array([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10.])
np.linspace(0, np.pi, 20)
# array([0.        , 0.16534698, 0.33069396, 0.49604095, 0.66138793,
#        0.82673491, 0.99208189, 1.15742887, 1.32277585, 1.48812284,
#        1.65346982, 1.8188168 , 1.98416378, 2.14951076, 2.31485774,
#        2.48020473, 2.64555171, 2.81089869, 2.97624567, 3.14159265])

 

3) 모든 요소가 0인 배열 생성 : np.zeros(shape, dtype=..)

np.zeros(10, dtype=int) # array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

 

4) 모든 요소가 1인 배열 생성 : np.ones(shape, dtype = ...)

np.ones(10) # array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])

 

5) 대각요소가 1인 배열 생성 1 : np.eye(n, m, k=K, dtype=..)

np.eye(3) 
# array([[1., 0., 0.],
#        [0., 1., 0.],
#        [0., 0., 1.]])

np.eye(4,4,2,'int') # K = 2 (2열 밀려남), dtype = 'int'
# array([[0, 0, 1, 0],
#        [0, 0, 0, 1],
#        [0, 0, 0, 0],
#        [0, 0, 0, 0]])

 

6) 대각요소가 1인 배열 생성 2: np.identify(n, dtype=..) # n*n 크기의 단위 행렬 생성

np.identity(5,dtype=int)
# array([[1, 0, 0, 0, 0],
#        [0, 1, 0, 0, 0],
#        [0, 0, 1, 0, 0],
#        [0, 0, 0, 1, 0],
#        [0, 0, 0, 0, 1]])

 

7) 초기화 되지 않은 배열 생성 : np.empty(shape, dtype=float)

np.empty(4) # array([0., 0., 0., 0.])

 

8) 난수 배열 생성

(1) rand()

np.random.rand(2,3)
# array([[0.8523509 , 0.53013047, 0.12733061],
#        [0.10158506, 0.71868225, 0.80807532]])

np.random.rand(2,3,4)
# array([[[0.77959976, 0.91697309, 0.47176178, 0.89987902],
#         [0.23081891, 0.45491162, 0.33181965, 0.01572869],
#         [0.48308224, 0.42361819, 0.02245016, 0.77470336]],

#        [[0.74350602, 0.66714276, 0.5760056 , 0.23347669],
#         [0.16620778, 0.44642812, 0.01710379, 0.80296654],
#         [0.61857977, 0.08923439, 0.92965589, 0.73801151]]])

(2) randint()

np.random.randint(5) # 0~5
np.random.randint(10,20) # 10~20
np.random.randint(10, 20, size = (2,3)) # 10~20. 2행 3열

 


 

[배열 기본 연산]

1) 동일한 크기의 array 간 연산 수행 : 합, 차, 곱, 나누기, 비교연산

 

2) 배열의 Broadcasting : 서로 크기가 다른 array들의 연산 가능하도록 자동적으로 변환

* 브로드캐스팅이 일어나는 조건
- 하나는 1차원이고 또 다른 하나는 다른 array의 행이나 열의 배열의 차원이 동일해야함.

arr1 = np.array([[1,3,4],[4,3,6]])
# array([[1, 3, 4],
#        [4, 3, 6]])
arr2 = np.array([10,11,12])
# array([10, 11, 12])

(arr1.shape, arr3.shape) # ((2, 3), (3,))
arr1 + arr3 # arr1의 1행에 arr3 더해지고, 2행에 더해지고..
# array([[11, 14, 16],
#        [14, 14, 18]])

 

<통계를 위한 연산>

sum(), mean(), max(), min(), var(), std(), cumsum() _ 누적합, cumprod() _ 누적곱

 

<행렬 연산>

1) 행렬곱 : A.dot(B) or np.dot(A,B)

2) 전치행렬 : A.transpose(), np.transpose(A) : 주대각선 기준으로 전치

3) 역행렬 : np.linalg.inv(A)

4) 행렬식 : np.linalg.det(A)

 > 연립 방정식의 해가 다르게 나오는 것을 보고 이 값이 해의 존재 여부(궁극적으로는 행렬의 가역 여부)를 '판별'한다는 뜻에서 determinant라는 용어가 탄생

 

<배열의 인덱싱과 슬라이싱>

1) 인덱싱

import random

np.random.seed(0)
arr1 = np.array(np.random.randint(0,10,size=10))
arr1 # array([5, 0, 3, 3, 7, 9, 3, 5, 2, 4])

arr1[9] # 4
arr1[0] # 5

(1) 여러개 원소 선택 : 배열명[[위치1, 위치2..]]

 > arr1[[9,0]] # array([4, 5])

(2) (2차원 이상) 자리지정 원소 선택 : 배열명[행번호, 열번호]

arr2 = arr1.reshape((2,5))
arr2
# array([[5, 0, 3, 3, 7],
#        [9, 3, 5, 2, 4]])

arr2[1,2] # 5

(3) (2차원 이상) 여러개 원소 선택 : 배열명[[~행~],[~열~]]

> arr2[[0,1],[2,4]] # (0,2) = 3, (1,4) = 4

(4) 조건을 만족하는 원소 선택 : 배열명[조건]

> arr2[arr2 > 4] # array([5, 7, 9, 5])

 

2) 슬라이싱 

(1) 1차원 : 배열명[시작위치:끝위치+1]

(2) (2치원 이상) 배열명[(행)시작위치:끝위치][(열)시작위치:끝위치]

# array([[5, 0, 3, 3, 7],
#        [9, 3, 5, 2, 4]])

arr2[0:2][1:3]
# array([[9, 3, 5, 2, 4]])

arr2[0][:3]
# array([5, 0, 3])

arr2[0:2][2]
# IndexError: index 2 is out of bounds for axis 0 with size 2

 - [인덱싱][인덱싱] 가능, [슬라이싱][슬라이싱] 가능, [인덱싱][슬라이싱] 가능, [슬라이싱][인덱싱] 불가

 

728x90