<jupyter_start><jupyter_text>NumPy 배열 연산: 유니버설 함수NumPy 배열의 연산은 아주 빠르거나 아주 느릴 수 있다.이 연산을 빠르게 만드는 핵심은 벡터화(vectorized) 연산을 사용하는 것인데,그것은 일반적으로 NumPy의 유니버설 함수(universal functions, ufuncs)을 통해 구현된다.<jupyter_code>import numpy as np
np.random.seed(0)
def compute_reciprocals(values):
    output = np.empty(len(values))
    for i in range(len(values)):
        output[i] = 1.0 / values[i]
    return output
big_array = np.random.randint(1, 10, size=1000000)
%timeit compute_reciprocals(big_array)<jupyter_output>1.85 s ± 41.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)<jupyter_text>UFuncs 소개 NumPy는 여러 종류의 연산에 대해 이러한 종류의 정적 타입 체계를 가진 컴파일된 루틴에 편리한 인터페이스를 제공한다.이를 **벡터화** 연산이라고 한다.<jupyter_code>values = np.random.randint(1, 10, size=5)
print(compute_reciprocals(values))
print(1.0 / values)
%timeit (1.0 / big_array)
np.arange(5) / np.arange(1, 6)
x = np.arange(9).reshape((3, 3))
2**x<jupyter_output><empty_output><jupyter_text>유니버설 함수(UFuncs) UFuncs에는 단일 입력값에 동작하는 단항 ufuncs와 두 개의 입력값에 동작하는 이항 ufuncs로 두 종류가 있다.이 두 유형의 함수 예제를 살펴보자.  배열 산술 연산 NumPy ufuncs는 파이썬의 기본 산술 연산자를 사용하기 때문에 자연스럽게 사용할 수 있다. 표준 덧셈, 뺄셈, 곱셈, 나눗셈 모두 사용할 수 있다.<jupyter_code>x = np.arange(4)
print('x      =', x)
print('x + 5  =', x + 5)
print('x - 5  =', x - 5)
print('x * 2  =', x * 2)
print('x / 5  =', x / 5)
print('x // 2 =', x // 2)
print('-x     =', -x)
print('x ** 2 =', x ** 2)
print('x % 2  =', x & 2)
# 이 연산들은 원하는 만큼 사용할 수 있으며 표준 연산 순서를 따른다.
-(0.5 * x + 1) ** 2
# 이 산술 연산은 모두 사용상 편의를 위해 NumPy에 내장된 특정 함수를 감싼 것이다.
# 예를 들어, + 연산자는 add 함수의 래퍼(wrapper) 함수다.
np.add(x, 2)<jupyter_output><empty_output><jupyter_text>절댓값 함수 절댓값 함수에 대응하는 NumPy ufunc는 np.absolute로, np.abs라는 별칭으로도 사용할 수 있다.<jupyter_code>x = np.array([ -2, -1, 0, 1, 2])
abs(x)
# 복소수 데이터도 처리가능
x = np.array([3 - 4j, 4 - 3j, 2 + 0j, 0 + 1j])
np.abs(x)<jupyter_output><empty_output><jupyter_text>삼각함수<jupyter_code>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))<jupyter_output>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]<jupyter_text>고급 Ufunc 기능 출력 지정 임시 배열을 생성하지 않고 지정한 배열을 이용해 원하는 메모리 위치에 직접 연산 결과를 쓸 수 있다.<jupyter_code>x = np.arange(5)
y = np.empty(5)
np.multiply(x, 10, out=y)
print(y)
y = np.zeros(10)
np.power(2, x, out=y[::2])
print(y)<jupyter_output>[ 1.  0.  2.  0.  4.  0.  8.  0. 16.  0.]<jupyter_text>집계 배열을 특정 연산으로 축소하고자 한다면 ufunc의 reduce 메서드를 사용하면 된다. reduce 메소드는 결과가 하나만 남을 때까지 해당 연산을 배열 요소에 반복해서 적용한다.<jupyter_code>x = np.arange(1, 6)
print(x)
np.add.reduce(x)
np.multiply.reduce(x)
# 계산의 중간 결과를 모두 저장하고 싶다면 accumulate 사용
np.add.accumulate(x)
np.multiply.accumulate(x)<jupyter_output><empty_output><jupyter_text>외적 (Outer products) ufunc는 outer 메소드를 이용해 서로 다른 두 입력값의 모든 쌍에 대한 출력값을 계산할 수 있다.이렇게 하면 코드 한 줄로 곱셈 테이블을 만드는 것과 같은 일을 할 수 있다.<jupyter_code>x = np.arange(1, 6)
print(x)
np.multiply.outer(x, x)<jupyter_output>[1 2 3 4 5]<jupyter_text>집계: 최솟값, 최댓값 그리고 그 사이의 모든 것 NumPy에서는 배열에서 쓸 수 있는 빠른 내장 집계 함수가 있다.  배열의 값의 합 구하기 배열 내 모든 값의 합계를 계산<jupyter_code>L = np.random.random(100)
# Python 내장 함수
sum(L)
# NumPy 함수
np.sum(L)
# Numpy에서의 연산이 훨씬 빠르다
# 그러나 sum과 np.sum은 같은 함수가 아니라 때로는 혼선을 일으킬 수 있다.
big_array = np.random.rand(1000000)
%timeit sum(big_array)
%timeit np.sum(big_array)<jupyter_output>180 ms ± 36.1 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
1.08 ms ± 195 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)<jupyter_text>최솟값과 최댓값<jupyter_code># Python
min(big_array), max(big_array)
# NumPy
np.min(big_array), max(big_array)
%timeit min(big_array)
%timeit np.min(big_array)
# 배열 객체 자체의 메소드 사용
print(big_array.max())<jupyter_output>0.9999992772471815<jupyter_text>다차원 집계<jupyter_code>M = np.random.random((3, 4))
print(M)
M.sum()
# 집계 함수는 어느 축(axis)을 따라 집계할 것인지를 지정하는 추가적인 인수를 취한다.
# 예를 들어, 각 열의 최솟값을 찾으려면 axis = 0으로 지정하면 된다.
M.min(axis=0)
# 행은 axis = 1
M.max(axis=1)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1481844946025515, 'fraction_numerical': 0.0640333660451423, 'mean_word_length': 4.033333333333333, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 3, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '11', 'dir': 'jupyter-structured-clean-dedup', 'id': '116820', 'license': 'MIT', 'n_tokens_mistral': 2717, 'n_tokens_neox': 2953, 'n_words': 533, 'path': 'numpy_practice_2.ipynb', 'repo_name': 'taylous/Python_Data_Science', 'size': '4076'}