배열 연산: 유니버설 함수
In [54]:
import numpy as np
from scipy import special
작은 연산 반복은 느리다
역수가 계산될 때마다 파이썬은 먼저 객체의 타입을 확인하고 해당 타입에 맞게 사용할 적절한 함수를 동적으로 검색한다
In [18]:
np.random.seed(0)
def compute_reciprocals(val):
output = np.empty(len(val))
for i in range(len(val)):
output[i] = 1.0 / val[i]
return output
val = np.random.randint(1, 10, size = 5)
%timeit compute_reciprocals(val)
big_val = np.random.randint(1, 100, size = 10000)
%timeit compute_reciprocals(big_val)
5.6 μs ± 22.7 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each) 10.7 ms ± 134 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Ufuncs
벡터화 연산을 통해 빠르게 계산
In [19]:
%timeit compute_reciprocals(big_val)
%timeit 1.0 / big_val
10.7 ms ± 159 μs per loop (mean ± std. dev. of 7 runs, 100 loops each) 6.17 μs ± 562 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
In [27]:
# 두 배열의 연산도 가능
np.arange(5) / np.arange(1, 6)
# 다차원 배열
x = np.arange(9).reshape(3, 3)
print(2 ** x)
[[ 1 2 4] [ 8 16 32] [ 64 128 256]]
NumPy 유니버설 함수(Ufuncs)
Ufuncs는 단항 Ufuncs와 이항 Ufuncs로 두 종류가 있다
단항 Ufuncs
- + -> np.add
- - -> np.subtract
- - -> np.negative
- * -> np.multiply
- / -> np.divide
- // -> np.floor_divide
- ** -> np.power
- % -> np.mod
단항 Ufuncs
- + -> np.add
- - -> np.subtract
- - -> np.negative
- * -> np.multiply
- / -> np.divide
- // -> np.floor_divide
- ** -> np.power
- % -> np.mod
- + -> np.add
- - -> np.subtract
- - -> np.negative
- * -> np.multiply
- / -> np.divide
- // -> np.floor_divide
- ** -> np.power
- % -> np.mod
In [37]:
x = np.arange(4)
print("x = ", x)
print("x + 5 = ", x + 5)
print("x * 5 = ", x * 5)
print("x / 5 = ", x / 5)
print("x // 5 = ", x % 5)
print("x + 5 = ", x + 5)
print("-x = ", -x)
print("x ** 2 = ", x ** 2)
print("x % 2 = ", x % 2)
# 이 연산들은 원하는 만큼 사용 가능하며 표준 연산 순서를 따른다
print(-(0.5 * x + 1) ** 2)
x = [0 1 2 3] x + 5 = [5 6 7 8] x * 5 = [ 0 5 10 15] x / 5 = [0. 0.2 0.4 0.6] x // 5 = [0 1 2 3] x + 5 = [5 6 7 8] -x = [ 0 -1 -2 -3] x ** 2 = [0 1 4 9] x % 2 = [0 1 0 1] [1. 2.25 4. 6.25]
In [50]:
# 절댓값 함수 np.abs
x = -np.arange(5)
print(np.abs(x))
# 복소수 데이터 처리, 이 경우 절댓값은 크기를 반환한다
x = np.array([3 - 4j, 4 - 3j, 2 + 0j, 0 + 1j])
print(np.abs(x),'\n')
# 삼각함수
# linspace(start, stop, num = 50, endpoint = True, retstep = False, dtype = None, axis = 0, *, device = None)
theta = np.linspace(0, np.pi, 3)
print("theta = ", theta)
print("sin(theta) = ", np.sin(theta))
print("cos(theta) = ", np.cos(theta))
print("tan(theta) = ", np.tan(theta), '\n')
# 역삼각함수
x = [-1, 0, 1]
print("arcsin(theta) = ", np.arcsin(x))
print("arccos(theta) = ", np.arccos(x))
print("arctan(theta) = ", np.arctan(x))
[0 1 2 3 4] [5. 5. 2. 1.] theta = [0. 1.57079633 3.14159265] sin(theta) = [0.0000000e+00 1.0000000e+00 1.2246468e-16] cos(theta) = [ 1.000000e+00 6.123234e-17 -1.000000e+00] tan(theta) = [ 0.00000000e+00 1.63312394e+16 -1.22464680e-16] arcsin(theta) = [-1.57079633 0. 1.57079633] arccos(theta) = [3.14159265 1.57079633 0. ] arctan(theta) = [-0.78539816 0. 0.78539816]
In [52]:
# 지수
x = [1, 2, 3]
print("x = ", x)
print("e^x = ", np.exp(x))
print("2^x = ", np.exp2(x))
print("3^x = ", np.power(3, x),'\n')
# 로그
x = [1, 2, 4, 10]
print("x = ", x)
print("ln(x) = ", np.log(x))
print("log2(x) = ", np.log2(x))
print("log10(x) = ", np.log10(x))
x = [1, 2, 3] e^x = [ 2.71828183 7.3890561 20.08553692] 2^x = [2. 4. 8.] 3^x = [ 3 9 27] x = [1, 2, 4, 10] ln(x) = [0. 0.69314718 1.38629436 2.30258509] log2(x) = [0. 1. 2. 3.32192809] log10(x) = [0. 0.30103 0.60205999 1. ]
특화된 유니버설 함수
In [57]:
# 감마 함수
x = [1, 5, 10]
print("gamma(x) = ", special.gamma(x))
# 오차 함수(가우스 적분), 그 보수와 역수
x = np.array([0, 0.3, 0.7, 1.0])
print("erf(x) = ", special.erf(x))
print("erfc(x) = ", special.erfc(x))
print("erfinv(x) = ", special.erfinv(x))
gamma(x) = [1.0000e+00 2.4000e+01 3.6288e+05] erf(x) = [0. 0.32862676 0.67780119 0.84270079] erfc(x) = [1. 0.67137324 0.32219881 0.15729921] erfinv(x) = [0. 0.27246271 0.73286908 inf]
고급 Ufunc 기능
In [60]:
# 출력 지정, 지정한 배열을 이용해 원하는 메모리 위치에 연산 결과를 쓸 수 있다
x = np.arange(5)
y = np.empty(5)
np.multiply(x, 10, out=y)
print(y)
[0.0e+000 4.9e-324 9.9e-324 1.5e-323 2.0e-323] [ 0. 10. 20. 30. 40.]
In [63]:
# 집계
x = np.arange(1, 6)
# reduce 멧드는 결과가 하나만 남을 때까지 해당 연산을 배열 요소에 반복해서 적용하낟
print(np.add.reduce(x))
print(np.multiply.reduce(x))
# 계산 중간 결과를 모두 저장하고 싶다면 accumulate
print(np.add.accumulate(x))
print(np.multiply.accumulate(x))
15 120 [ 1 3 6 10 15] [ 1 2 6 24 120]
In [64]:
# 외적(Outer products)
# outer 메서드를 이용해 서로 다른 두 입력값의 모든 쌍에 대한 출력값을 계산 할 수 있다
x = np.arange(1, 6)
np.multiply.outer(x, x)
Out[64]:
array([[ 1, 2, 3, 4, 5], [ 2, 4, 6, 8, 10], [ 3, 6, 9, 12, 15], [ 4, 8, 12, 16, 20], [ 5, 10, 15, 20, 25]])
집계: 최솟값, 최댓값, 그리고 그 사이의 모든 것
대용량 데이터에 직면했을 때 보편적인 요약 통계는 평균, 표준편차겠지만(합, 곱, 중앙값, 최솟값, 최댓값, 분위 수 등)도 유용하다
In [67]:
# 배열의 값 구하기
# 파이썬 내장함수 sum, min, max 보다 np.sum,min,max가 훨씬 빠르다
L = np.random.random(100)
print(np.sum(L))
print(np.min(L), np.max(L))
51.18689942644107 0.02105699578930975 0.9894734658470377
In [72]:
# 다차원 집계
M = np.random.random((3, 4))
print(M,'\n')
# 집계 함수는 축(axis)에 따라 추가적인 인수를 취한다
# 예를들어 각 열의 최솟값을 찾으려면 axis = 0이다
print(M.min(axis = 0))
print(M.max(axis = 1))
[[0.86527541 0.87522277 0.4375864 0.99733631] [0.2828003 0.09106374 0.56719497 0.00747177] [0.47416375 0.83680379 0.41970708 0.20399237]] [0.2828003 0.09106374 0.41970708 0.00747177] [0.99733631 0.56719497 0.83680379]
기타 집계 함수
- np.sum : 요소의 합 계산
- np.prod : 요소의 곱 계산
- np.mean : 요소의 평균 계산
- np.std : 표준 편차 계산
- np.var : 분산 계산
- np.min : 최솟값 찾기
- np.max : 최댓값 찾기
- np.argmin : 최솟값의 인덱스 찾기
- np.argmax : 최댓값의 인덱스 찾기
- np.median : 요소의 중앙값 계산
- np.percentile 요소의 순위 기반 백분위 수 계산
- np.any : 요소 중 참이 있는지 검사
- np.all : 모슨 요소가 참인지 검사
누락된 경우를 NaN으로 표시 할때는 np.nan함수를 해주면 된다
In [ ]:
'Data science > 데이터 기초,시각화' 카테고리의 다른 글
Pandas 기초(2) (0) | 2024.09.12 |
---|---|
Pandas 기초(1) (0) | 2024.09.11 |
NumPy 기초(3) (0) | 2024.09.01 |
NumPy 기초(1) (1) | 2024.08.21 |
Jupyter Notebook 기본 (0) | 2022.05.14 |