<jupyter_start><jupyter_text>넘파이 4편: 고급 넘파이  주요 내용 부록 A(p. 587)의 내용 중 가장 많이 사용되는 고급 기능을 다룬다.* 어레이 조작: 모양 변형, 어레이 쪼개기/쌓기* 브로드캐스팅  기본 설정 `numpy` 모듈과 시각화 도구 모듈인 `matplotlib.pyplot`에 대한 기본 설정을 지정한다.<jupyter_code># 넘파이
import numpy as np
# 램덤 시드
np.random.seed(12345)
# 어레이 사용되는 부동소수점들의 정확도 지정
np.set_printoptions(precision=4, suppress=True)

# 파이플롯
import matplotlib.pyplot as plt
# 도표 크기 지정
plt.rc('figure', figsize=(10, 6))<jupyter_output><empty_output><jupyter_text>A.2 어레이 조작 고급 기법 (p. 590) 어레이를 조작하는 몇 가지 중요한 고급 기법을 살펴본다.   A.2.1 어레이 모양 변형 (p. 590)  `reshape()` 메서드 `reshape()` 메서드를 활용하여 지정된 튜플의 모양으로 주어진 어레이의 모양을 변형한다.단, 항목의 수가 변하지 않도록 모양을 지정해야 한다.예를 들어, 길이가 8인 1차원 어레이가 다음과 같다.<jupyter_code>arr = np.arange(8)
arr<jupyter_output><empty_output><jupyter_text>이제 (4, 2) 모양의 2차원 어레이로 모양을 변형할 수 있다.<jupyter_code>arr.reshape((4, 2))<jupyter_output><empty_output><jupyter_text>항목의 수만 같으면 임의의 차원의 어레이를 임의의 차원의 어레이로 변형시킬 수 있다.<jupyter_code>arr.reshape((4, 2)).reshape((2, 2, 2))<jupyter_output><empty_output><jupyter_text>`-1`의 역할 어레의 모양을 지정할 때 튜플의 특정 위치에 -1을 사용할 수 있다.그러면 그 위치의 값은 튜플의 다른 항목의 정보를 이용하여 자동으로 지정된다.예를 들어, 아래 코드에서 -1은 4를 의미한다. 이유는 20개의 항목을 5개의 행으로 이루어진 2차원 어레이로 지정하려면 열은 4개 있어야 하기 때문이다.<jupyter_code>arr = np.arange(20)
arr.reshape((5, -1))
arr.reshape((5, 4))<jupyter_output><empty_output><jupyter_text>동일한 이유로 아래에서 -1은 5를 의미한다.<jupyter_code>arr.reshape((2, -1, 2))
arr.reshape((2, 5, 2))<jupyter_output><empty_output><jupyter_text>A.3.1 차원 추가(p. 604) 어레이에 임의의 축을 추가하는 방식으로 1차원 커진 어레이를 생성할 수 있다.어느 축을 지정하느냐에 따라 다른 모양을 갖게 된다.  예제 다음 길이가 3인 1차원 어레이를 이용하자.* `np.random.normal()` 함수는 `np.random.randn()` 함수를 일반화하여 정균분포를 따르면서    무작위 수를 생성한다.     평균값과 표준편차를 지정할 수 있으며, 기본값은 평균값 0, 표준편차 1로 표준 정규분포를 따르도록 한다.<jupyter_code>arr_1d = np.random.normal(size=3)
arr_1d<jupyter_output><empty_output><jupyter_text>아래 코드는 열 관련 축을 추가한다.<jupyter_code>arr_1d[:, np.newaxis]<jupyter_output><empty_output><jupyter_text>`reshape()` 메소드로도 동일한 결과를 얻을 수 있다.<jupyter_code>arr_1d.reshape((3, 1))<jupyter_output><empty_output><jupyter_text>아래 코드는 행 관련 축을 추가한다.<jupyter_code>arr_1d[np.newaxis, :]
arr_1d.reshape((1,3))<jupyter_output><empty_output><jupyter_text>예제 2차원 어레이에 축을 추가하면 3차원 어레이가 생성되며, 작동방식은 앞서와 동일하다.<jupyter_code>arr = np.random.randn(4, 3)
arr
arr[:,:,np.newaxis].shape
arr[:,:,np.newaxis]
arr[:,np.newaxis,:].shape
arr[:,np.newaxis,:]<jupyter_output><empty_output><jupyter_text>`ravel()` 메서드와 `flatten()` 메서드 두 메서드 모두 1차원 어레이를 반환한다. 즉, 차원을 모두 없앤다.<jupyter_code>arr = np.arange(15).reshape((5, 3))
arr
arr1 = arr.ravel()
arr1
arr2 = arr.flatten()
arr2<jupyter_output><empty_output><jupyter_text>차이점은 `ravel()` 메서드는 뷰(view)를 사용하는 반면에 `flatten()` 메서드는 어레이를 새로 생성한다.예를 들어, 아래처럼 `arr1`의 항목을 변경하면 `arr`의 항목도 함께 변경된다.<jupyter_code>arr1[0] = -1
arr<jupyter_output><empty_output><jupyter_text>`arr2`은 `arr`과 전혀 상관이 없다.<jupyter_code>arr2[0] = -7
arr<jupyter_output><empty_output><jupyter_text>A.2.3 어레이 쪼개기/쌓기 (p. 594)  `np.split()` 함수 어레이를 지정된 기준에 따라 여러 개의 어레이로 쪼갠다.반환값은 쪼개진 어레이들의 리스트다.아래 예제를 살펴보자.<jupyter_code>arr = np.random.randn(7, 5)
arr<jupyter_output><empty_output><jupyter_text>`np.split()` 함수의 인자는 정수이거나 정수들의 리스트가 사용된다.먼저, 정수 리스트가 들어오면 축이 정한 방향으로 리스트에 포함된 정수를 이용하여 여러 개의 구간으로 쪼갠다.아래 코드는 행을 기준으로 행의 인덱스를 0-1, 2, 3-4, 5-7 네 개의 구간으로 쪼갠다.따라서 결과는 네 개의 어레이로 이루어진 리스트가 되며,각 어레의 모양은 다음과 같다.```python(2, 5), (1, 5), (2, 5), (2, 5)```<jupyter_code>np.split(arr, [2, 3, 5],axis=0)<jupyter_output><empty_output><jupyter_text>반면에 열을 기준으로 0, 1-2, 3-4 3개의 구간으로 쪼개면 다음과 같으며,각 어레이의 모양은 다음과 같다.```python(7, 1) (7, 2), (7, 2)```<jupyter_code>np.split(arr, [1, 3],axis=1)<jupyter_output><empty_output><jupyter_text>`np.vsplit()`/`np.hsplit()` 함수 두 함수는 `np.split()` 함수에 축을 각각 0과 1로 지정한 함수이다. * `np.vsplit(arr, z)` = `np.split(arr, z, axis=0)`<jupyter_code>np.vsplit(arr, [2, 3, 5])<jupyter_output><empty_output><jupyter_text>* `np.hsplit(arr, z)` = `np.split(arr, z, axis=1)`<jupyter_code>np.hsplit(arr, [1, 3])<jupyter_output><empty_output><jupyter_text>`np.concatenate()` 함수 두 개의 어레이를 이어 붙이다.지정되는 축에 따라 좌우로 또는 상하로 이어붙인다.아래 두 어레이가 주어졌다고 가정하다.<jupyter_code>arr1 = np.array([[1, 2, 3], [4, 5, 6]])
arr1
arr2 = np.array([[7, 8, 9], [10, 11, 12]])
arr2<jupyter_output><empty_output><jupyter_text>위아래로 이어붙이려면 축을 0으로 정한다.__주의사항:__ 인자가 길이가 2인 리스트이다.<jupyter_code>np.concatenate([arr1, arr2], axis=0)<jupyter_output><empty_output><jupyter_text>좌우로 이어붙이려면 축을 1로 정한다.<jupyter_code>np.concatenate([arr1, arr2], axis=1)<jupyter_output><empty_output><jupyter_text>`np.vstack()`/`np.hstack()` 함수 두 함수는 `np.concatenate()` 함수에 축을 각각 0과 1로 지정한 함수이다.__주의사항:__ 인자가 길이가 2인 튜플이다. * `np.vstack((x, y))` = `np.concatenate([x, y], axis=0)`<jupyter_code>np.vstack((arr1, arr2))<jupyter_output><empty_output><jupyter_text>* `np.hstack((x, y))` = `np.concatenate([x, y], axis=1)`<jupyter_code>np.hstack((arr1, arr2))<jupyter_output><empty_output><jupyter_text>`np.r_[]`/`np.c_[]` 객체 `vstack()`/`hstack()` 과 동일한 기능을 수행하는 특수한 객체들이다.아래 세 개의 어레이를 이용하여 사용법을 살펴본다.<jupyter_code>arr = np.arange(6)
arr
arr1 = np.arange(6).reshape((3, 2))
arr1
arr2 = np.random.randn(3, 2)
arr2<jupyter_output><empty_output><jupyter_text>아래 코드는 `np.vstack((arr1, arr2))`와 동일하다.<jupyter_code>np.r_[arr1, arr2]
np.vstack([arr1, arr2])<jupyter_output><empty_output><jupyter_text>아래 코드는 `np.hstack((arr1, arr2))`와 동일하다.<jupyter_code>np.c_[arr1, arr2]
np.hstack((arr1, arr2))<jupyter_output><empty_output><jupyter_text>행 또는 열의 크기를 적절하게 맞출 수 있는 어떤 조합도 가능하다.<jupyter_code>np.c_[np.r_[arr1, arr2], arr]<jupyter_output><empty_output><jupyter_text>A.3 브로드캐스팅 (p. 601)  예제<jupyter_code>arr = np.arange(6).reshape((2,3))
arr<jupyter_output><empty_output><jupyter_text>`arr * 4` 아래 어레이의 곱셈과 동일하다.<jupyter_code>arr * 4<jupyter_output><empty_output><jupyter_text>예제<jupyter_code>arr2 = np.arange(4).reshape((4,1)).repeat(3,axis=1)
arr2
arr3 = np.arange(1, 4)
arr3
arr2 + arr3<jupyter_output><empty_output><jupyter_text><jupyter_code>arr3a = np.arange(1, 4).reshape((1,3))
arr3a
arr2 + arr3a<jupyter_output><empty_output><jupyter_text>예제<jupyter_code>arr4 = np.arange(1, 5).reshape((4,1))
arr4
arr2 + arr4<jupyter_output><empty_output><jupyter_text>예제<jupyter_code>arr6 = np.arange(24).reshape((3, 4, 2))
arr6
arr7 = np.arange(8).reshape((4, 2))
arr7
arr6 + arr7<jupyter_output><empty_output><jupyter_text>예제<jupyter_code>arr = np.random.randn(4, 3)
arr
arr.mean(0)
demeaned = arr - arr.mean(0)
demeaned
demeaned.mean(0)<jupyter_output><empty_output><jupyter_text>예제<jupyter_code>arr
row_means = arr.mean(1)
row_means
row_means.reshape((4, 1))
demeaned = arr - row_means.reshape((4, 1))
demeaned.mean(1)<jupyter_output><empty_output><jupyter_text>A.3.2 브로드캐스팅으로 어레이에 값 대입하기 (p. 606)<jupyter_code>arr = np.zeros((4, 3))
arr
arr[:] = 5
arr
col = np.array([1.28, -0.42, 0.44, 1.6])
arr[:] = col[:, np.newaxis]
arr
arr[:2] = [[-1.37], [0.509]]
arr<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1696415400501549, 'fraction_numerical': 0.04440182917834489, 'mean_word_length': 6.290322580645161, 'pattern_counts': {'":': 0, '<': 149, '<?xml version=': 0, '>': 149, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '37', 'dir': 'jupyter-structured-clean-dedup', 'id': '460594', 'license': 'Apache-2.0', 'n_tokens_mistral': 4448, 'n_tokens_neox': 5050, 'n_words': 661, 'path': 'notebooks/pydata04_numpy_basics_4.ipynb', 'repo_name': 'kimota3/pydata', 'size': '6779'}