Numpy
1. Numpy Array and Operation
- numpy의 기본적인 사용법에 대해서 배워봅니다.
- numpy에서 numpy.array를 만드는 여러가지 방법과 지원하는 연산자에 대해서 공부합니다.
1.1. Numpy Array creation
# numpy 라이브러리를 불러옵니다.
import numpy as np
# 파이썬 리스트 선언
data = [1, 2, 3, 4, 5]
# 파이썬 2차원 리스트(행렬) 선언
data2 = [[1,2],[3,4]]
# 파이썬 list를 numpy array로 변환합니다.
# numpy array를 만드는 방식의 대부분은 파이썬 리스트를 np.array로 변환하는 방식입니다.
arr = np.array(data)
arr
>>> array([1, 2, 3, 4, 5])
# 2차원 리스트를 np.array로 만듭니다.
# 2차원 리스트를 np.array로 만듭니다.
arr2 = np.array(data2) # data2라는 리스트를 numpy array로 만들어라.
arr2 # 2차원 numpy array -> 행렬!
>>> array([[1, 2],
[3, 4]])
# 0부터 9까지 숫자를 자동으로 생성한 array
np.array(list(range(10)))
np.arange(10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 10부터 99까지 숫자를 자동으로 생성한 array
np.arange(10,100)
더보기
array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
95, 96, 97, 98, 99])
arr.shape (5, ) != (5,1)
arr2.shape (2 , 2)
>>> (2, 2)
1.2. Reshaping array
# 3 x 3 행렬을 만들어봅시다
x = np.array([[1,2,3],
[4,5,6],
[7,8,9]])
x
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
# reshape을 이용하여 만들어봅시다.
np.arange(1,10).reshape(3, 3) # (9, )-> (3, 3)
array([[0],
[1],
[2],
[3],
[4],
[5]])
# 펼치기
x.reshape(-1, )
(-1,) (9, ) numpy에 reshape 함수에 -1를 넣으면 -1은 나머지의 세트와 합쳐서 자동계산
(3, 3)
1.3. Concatenation of arrays
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
arr1 + arr2 = ? -> 벡터연산이 됨/ 리스트타입과는 다름
arr1 + arr2
>>> array([5, 7, 9])
arr1와 arr2를 합칩니다
np.concatenate([arr1, arr2])
>>> array([1, 2, 3, 4, 5, 6])
# stacking vertically
np.vstack([arr1, arr2])
array([[1, 2, 3],
[4, 5, 6]])
# stacking horizontally
np.hstack([arr1, arr2])
array([1, 2, 3, 4, 5, 6])
1.4. Array Arithmetic (like vector) --> Universal Function
# v1 = (1, 2, 3), v2 = (4, 5, 6) 벡터 2개 생성하기.
v1 = np.array([1, 2, 3])
v2 = np.array([4, 5, 6])
# 리스트로 더하기 연산해보기
L1 = [1, 2, 3]
L2 = [4, 5, 6]
L1 + L2
[1, 2, 3, 4, 5, 6]
# vector addition 백터연산
v1 + v2
array([5, 7, 9])
# vector subtraction 백터연산
v1 - v2
array([-3, -3, -3])
# (not vector operation) elementwise multiplication
v1 * v2
array([ 4, 10, 18])
# dot product
v1 @ v2 # 1x4 + 2X5 + 3X6
32
1.5. Broadcast and Universal Function
- 서로 크기가 다른 numpy array를 연산할 때, 자동으로 연산을 전파(broadcast)해주는 기능.
- 행렬곱 연산을 할 때 편리하다.
arr1 = np.array([1, 2, 3])
arr2 = np.array([[-1,-1,-1],[1, 1, 1,]])
arr2.shape
(2, 3)
# 2개의 array를 더해보면?
arr1 + arr2 # 2->2->3(v)
array([[0, 1, 2],
[2, 3, 4]])
# 2개의 array를 곱해보면? (**)
arr1 * arr2
array([[-1, -2, -3],
[ 1, 2, 3]])
- Universal Function : broadcast 기능을 확장해서, numpy array의 모든 원소에 동일한 함수를 반복문으로 적용한 것과 같은 효과를 내는 기능.
# f = lambda x : 1/x
f = lambda x : 1/x
arr1= np.array([1., 2., 3.])
for i in range(arr1.shape[0]):
arr1[i] = f(arr1[i])
print(arr1)
arr1= np.array([1., 2., 3.])
print(1 / arr1) # Universal Function
[1. 0.5 0.33333333]
[1. 0.5 0.33333333]
# f = lambda x : x + 2
arr1 = arr1 * 3
arr1
array([15., 18., 21.])
1.6. Indexing
- numpy array의 indexing은 python list의 indexing과 같다!
arr1 = np.arange(10)
arr1
>>> array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 첫번째 원소
arr1[0]
>>> 0
# 마지막 원소
arr1[-1]
>>> 9
# 앞에서부터 원소 3개 slicing
arr1[:3]
>>> array([0, 1, 2])
arr2 = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]])
arr2
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
# arr2의 2row, 3column 원소 = 7
arr2[1][2]
arr2[1, 2] # numpy array indexing에서 추가된것!
>>> 7
# arr2의 세번째 column [3, 7, 11]
arr2[0, 2]
arr2[1, 2]
arr2[2, 2]
arr2[ : , 2]
array([ 3, 7, 11])
# arr2의 두번째 row
# arr2의 두번째 row
arr2[ 1, : ]
array([5, 6, 7, 8])
2. Numpy Methods
- numpy에서 사용되는 여러가지 함수들을 사용해봅시다.
2.1. Math Functions
# 표준정규분포에서 random sampling을 한 원소를 가지는 5x3 행렬을 만든다.
mat1 = np.random.randn(5, 3)
mat1
array([[ 2.45760313, 0.51453728, -0.60537909],
[ 1.66107988, 1.13174898, 0.45791088],
[ 0.59030187, 0.15268791, -0.70872446],
[ 0.21876355, 1.07496683, -1.5666292 ],
[-0.38959035, -0.35822517, 1.36738604]])
# mat1에 절대값 씌우기
np.abs(mat1)
array([[2.45760313, 0.51453728, 0.60537909],
[1.66107988, 1.13174898, 0.45791088],
[0.59030187, 0.15268791, 0.70872446],
[0.21876355, 1.07496683, 1.5666292 ],
[0.38959035, 0.35822517, 1.36738604]])
# mat1 제곱하기
np.square(mat1)
array([[6.03981315, 0.26474862, 0.36648384],
[2.75918638, 1.28085576, 0.20968238],
[0.3484563 , 0.0233136 , 0.50229035],
[0.04785749, 1.15555368, 2.45432706],
[0.15178064, 0.12832527, 1.86974458]])
# mat1의 제곱근 구하기
np.sqrt(mat1) nan = not a number 루트안에 마이너스는 허수가 나와서 실수로 표현안됨
/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:2: RuntimeWarning: invalid value encountered in sqrt
array([[1.56767443, 0.71731254, nan],
[1.28882888, 1.06383692, 0.67669113],
[0.76831105, 0.390753 , nan],
[0.46772165, 1.03680607, nan],
[ nan, nan, 1.16935283]])
# linear algebra functions
# C++ 프로그래밍 언어에서 벡터(std::vector)는 유동적으로 크기 조절이 가능한 배열 자료 구조를 구현한 것이다
# 파이썬에서 벡터는 한 개 또는 그이상의 "스칼라" 값으로 구성된 튜플이다.
vec = np.array([1, 2, 2])
# 1. norm (백터의 크기)
np.linalg.norm(vec) ---> vector L2 norm
# 2. eigenvalue(선형대수의 고유값)
mat = np.array([[1,2],
[3,4]])
np.linalg.eig(mat)
(array([-0.37228132, 5.37228132]), array([[-0.82456484, -0.41597356],
[ 0.56576746, -0.90937671]]))
2.2. Aggregation functions
#rand는 0~1 사이에 아무거나 찍어준다
mat2 = np.random.rand(3, 2) #rand는 0~1 사이에 아무거나 찍어준다
mat2
array([[0.33702761, 0.8267591 ],
[0.37960553, 0.90505923],
[0.42097973, 0.38001594]])
# Summation
# Summation
np.sum(mat2) # 전체
np.sum(mat2,axis=0) # column 대로 더했음
np.sum(mat2,axis=1) # row 대로 더함
array([1.13761286, 2.11183427])
# mean
np.mean(mat2) # 전체평균
np.mean(mat2,axis=0) # column 대로 평균
np.mean(mat2,axis=1) # raw 대로 평균
array([0.58189335, 0.64233238, 0.40049783])
# std / Numpy.std() 함수는 지정된 축을 따라 주어진 배열의 표준 편차를 계산합니다.
np.std(mat2)
0.23172147686805705
# min, max
np.min(mat2, axis = 0) # column
np.max(mat2, axis = 1) # raw
array([0.8267591 , 0.90505923, 0.42097973])
# 최소값이 있는 Index
np.argmin(mat2, axis=0 )
array([0, 2])
# 최대값이 있는 Index
np.argmax(mat2, axis=1 )
array([1, 1, 0])
# 그냥 정렬 (오름차순 정렬만 지원합니다)
np.sort(mat2)
array([[0.33702761, 0.8267591 ],
[0.37960553, 0.90505923],
[0.38001594, 0.42097973]])
np.sort(mat2,axis=0) # column 행
array([[0.33702761, 0.38001594],
[0.37960553, 0.8267591 ],
[0.42097973, 0.90505923]])
# 만약에 내림차순을 하겠다?
np.sort(mat2,axis=0)[::-1]
array([[0.42097973, 0.90505923],
[0.37960553, 0.8267591 ],
[0.33702761, 0.38001594]])
# index를 정렬 /원래 어디에 있어는지 사용
np.argsort(mat2 ,axis = 0)
array([[0, 2],
[1, 0],
[2, 1]])
3. Performance Check
- Universal Function 기능을 통해 반복문을 사용한 것보다 훨씬 빠른 성능을 냅니다.
- 직접 실험을 통해 그 차이를 확인해보겠습니다.
def reverse_num(values):
output = np.empty(len(values))
for i in range(len(values)):
output[i] = 1.0 / values[i]
return output
# 1부터 100까지 범위에서 100000000개를 랜덤으로 뽑아서 array를 만듭니다.
big_array = np.random.randint(1,100, 100000000)
big_array
array([90, 91, 70, ..., 99, 3, 27])
%timeit reverse_num(big_array)
1 loop, best of 5: 2.19 s per loop
# numpy의 universal function이 훨씬 빠르다! 단, 크기가 클떄 좋음.
%timeit 1.0 / big_array
100 loops, best of 5: 1.99 ms per loop
'Python > Data Analysis Library' 카테고리의 다른 글
Part03 Chapter.02 데이터 분석 라이브러리 06. Pandas method (실습) (0) | 2022.07.18 |
---|---|
Part03 Chapter.02 데이터 분석 라이브러리 05. Pandas DataFrame (0) | 2022.07.18 |
Part03 Chapter.02 데이터 분석 라이브러리 04. Pandas를 사용하는 이유 (0) | 2022.07.18 |
Part03 Chapter.02 데이터 분석 라이브러리 02. Numpy array (0) | 2022.07.12 |
Part 03 Chapter.02 데이터 분석 라이브러리 01. Numpy를 사용하는 이유 (0) | 2022.07.12 |