# [Numpy] Numpy 기능

## Numpy 배열

---

- ndarray (N-dimensional array) → n차원까지 제공

- 하나의 배열 속 값들은 모두 동일한 자료형

![Image](https://upload.cafenono.com/image/slashpagePost/20250201/152130_n3woBAS4mcDyvJJaFH?q=80&s=1280x180&t=outside&f=webp)

- 1 차원: 실수 / 2 차원: Boolean / 3 차원: 정수

- 축의 개수 (n차원 → n개), 축은 0부터 시작

![Image](https://upload.cafenono.com/image/slashpagePost/20250201/152138_ArFZpIOH8SHxKchJRk?q=80&s=1280x180&t=outside&f=webp)

- 첫 괄호의 개수 = 차원의 개수

## 배열 속성 확인 및 변경

---

![Image](https://upload.cafenono.com/image/slashpagePost/20250201/152157_ZPXSICSooDum9QpixS?q=80&s=1280x180&t=outside&f=webp)

```javascript
ndarray.dtype # 데이터의 자료형 확인
>> float64

ndarray.ndim  # 데이터의 차원 확인
>> 3

ndarray.shape # 데이터의 축(axis)별 크기 확인)
>> (2, 4, 3)

ndarray.size  # 데이터의 전체 요소 개수 확인
>> 24
```

![Image](https://upload.cafenono.com/image/slashpagePost/20250201/152213_u9WrSAbOktpYL8tN2c?q=80&s=1280x180&t=outside&f=webp)

```javascript
# 데이터의 자료형 변경
array.astype('int64')
```

```javascript
# 형태 변환
np.arange(0, 6)
>> arrray ([0, 1, 2, 3, 4, 5])

# 지정한 shape으로 형태 변환 (shape)
np.arange(6).reshape(3, 2)
>> array([[0, 1], 
                    [2, 3], 
                    [4, 5]])

# 1차원으로 형태 변환
np.arange(6).reshape(3, 2).ravel()
>> array([0, 1, 2, 3, 4, 5])

# 전치 (Transpose) 변환
np.arange(6).reshpae(3, 2).T
>> array([[0, 2, 4], 
                    [1, 3, 5]])
```

## 배열 생성

---

- 유형 1: Python의 list혹은 tuple을 ndarray로 바꾸기

```javascript
np.array([1, 2, 3, 4, 5]) # Python의 list나 tuple을 numpy 배열로 만듦
>> array([1, 2, 3, 4 ,5 ])
```

- 유형 2: 모두 같은 원소로 이우러진 ndarray 생성

```javascript
np.zeros((2, 3))   # 모든 워소가 0인 배열 생성 (shape, dtype)
>> array([[0., 0., 0.], 
                    [0., 0., 0.]])

np.ones((2, 3))    # 모든 원소가 1인 배열 생성 (shape, dtype)
>> array([[1., 1., 1.], 
                    [1., 1., 1.]])

np.full((2, 3), 5) # 모든 원소가 n인 배열 생성 (shape, n)
>> array([[5, 5, 5], 
                    [5, 5, 5]])
```

- 유형 3. 연속적인 원소로 이루어진 ndarray 생성

```javascript
np.arange(1, 9, 2) # start 이상 stop 미만 간격이 step인 배열 생성 (start, stop, step)
>> array([1, 3, 5, 7])

np.linspace(1, 9, 5) # start 이상 stop 이하 n등분하여 배열 생성 (start, stop, n)
>> array([1., 3., 5., 7., 9.])
```

- 유형 4: random모듈, 주어진 배열 존재

```javascript
data = np.array([1, 2, 3, 4, 5])

#주어진 배열에서 임의로 원소 선택하여 배열 생성 (data, shape)
np.random.choice(data, (2, 3)) 
>> array([[5, 5, 2], 
                    [2, 4, 2]])

#주어진 배열의 순서 임의로 변경 (data)
np.random.shuffle(data)
data
>> array([5, 1, 4, 3, 2])
```

- 유형 5: random모듈, 주어진 배열 존재 X

```javascript
# [0, 1)에서 각 구간의 난수 수가 균등분포 따르도록 샘플링 (data)
np.random.rand(2, 3)
>> array([[0.15587761, 0.02523678, 0.55856038],
          [0.37309179, 0.38754009, 0.80666399]])

# 난수가 표준정규분포를 따르도록 샘플링 (data)
np.random.randn(2, 3)
>> array([[0.48001543, 0.95958113, 0.07930882],
          [0.41110413, 0.1820168 , 0.31100255]])

# start 이상 stop 미만인 정수 샘플링 (start, stop, shape)
np.random.randint(1, 10, (2, 3))
>> array([[2, 5, 5],
          [1, 7, 7]])
```

## 배열 연산

---

- 사칙 연산: numpy는 같은 위치에 있는 원소끼리 연산

    - array1 - array2: 같은 위치에 있는 원소끼리 덧셈

    - array1 + array2: 같은 위치에 있는 원소끼리 뺼셈

    - array1 * array2: 같은 위치에 있는 원소끼리 곱셈

    - array1 / array2: 같은 위치에 있는 원소끼리 나눗셈

![Image](https://upload.cafenono.com/image/slashpagePost/20250201/152241_TlbHZHq6SQfCcOIY06?q=80&s=1280x180&t=outside&f=webp)

- 행렬의 곱

    - 앞 행렬의 열 개수 = 뒤 행렬의 행 개수

    - array @ array2

![Image](https://upload.cafenono.com/image/slashpagePost/20250201/152259_0a9C3t0sWkvb2OrTuE?q=80&s=1280x180&t=outside&f=webp)

```javascript
# 위 사진 모양의 'arr1'과 'arr2' 배열 생성
arr1 = np.array([[1, 2, 5, 4],
                 [4, 3, 1, 3]])
print(arr1)

arr2 = np.arange(1, 9).reshape(2, 4)
print()

# arr1과 arr2 더하기
arr1 + arr2

# arr1과 arr2 빼기
arr1 - arr2

# arr1과 arr2 곱하기
arr1 * arr2

# arr1과 arr2 나누기
arr1 / arr2

# arr1과 arr2.T 행렬의 곱 수행
arr2 = arr2.T
arr1 @ arr2

# arr1과 arr2.T 행렬의 곱 수행
np.dot(arr1, arr2)
```

- Numpy 집계 함수

| **함수** | **설명** |
| --- | --- |
| np.**sum**(array) | 전체 원소의 합을 계산 |
| np.**mean**(array) | 전체 원소의 평균을 계산 |
| np.**std**(array), np.**var**(array) | 전체 원소의 표준편차, 분산을 계산 |
| np.**min**(array), np.**max**(array) | 전체 원소의 최솟값, 최댓값 반환 |
| np.**argmin**(array), np.**argmax**(array) | 전체 원소의 최솟값, 최댓값이 위치한 인덱스 반환 |
| np.**cumsum**(array) | 첫 원소부터 끝 원소까지의 누적합 반환 |
| np.**sumprod**(array) | 첫 원소부터 끝 원소까지의 누적곱 반환 |

## 브도르캐스팅

---

다른 형태의 배열도 연산할 수 있도록 배열의 형태를 변환하는 것 (단, 아래 3가지 경우에만 가능)

- (경우1) 하나의 배열이 원소 1개로 이루어진 배열인 경우

![Image](https://upload.cafenono.com/image/slashpagePost/20250201/152358_DCgFyOBxwIqK3jx58N?q=80&s=1280x180&t=outside&f=webp)

```javascript
# 경우1: 하나의 배열이 원소 1개로 이루어진 배열인 경우
arr1 = np.array([[0, 0, 0], [1, 1, 1], [2, 2, 2]])
arr2 = np.array([1])
arr1 + arr2
```

- (경우2) 하나의 배열이 1차원인 경우

![Image](https://upload.cafenono.com/image/slashpagePost/20250201/152406_ba7uHBuSpYdtxaPGCy?q=80&s=1280x180&t=outside&f=webp)

```javascript
# 경우2: 하나의 배열이 1차원인 경우
arr1 = np.array([[0, 0, 0], [1, 1, 1], [2, 2, 2]])
arr2 = np.array([1, 2, 3])
arr1 + arr2
```

![Image](https://upload.cafenono.com/image/slashpagePost/20250201/152417_twx2touXtw7TfThQEV?q=80&s=1280x180&t=outside&f=webp)

```javascript
arr1 = np.array([0, 1, 2]).reshape(3, 1)
arr2 = np.array([1, 2, 3])
arr1 + arr2
```

## 인덱싱과 슬라이싱

---

- 인덱스: 여러 원소를 가지고 있는 객체(리스트, 튜플, 배열 등)에 부여되는 번호

- 슬라이싱: 여러 원소를 가지고 있는 객체의 일부를 추출하는 것

- 파이썬의 List와 동일하게 ndarray도 인덱싱과 슬라이싱 사용 가능

### Indexing (인덱싱)

```javascript
# 1부터 10까지 수 중 랜덤하게 6개의 수가 추출된 'arr1'이라는 배열
# shape: 3X2인 2차원 배열
arr1 = np.random.randint(1, 11, (3, 2))
arr1

# 1행 출력
arr1[0]

# 2행 1열의 원소 출력
arr1[1][0]

arr1[1, 0]
```

### Slicing (슬라이싱)

- 1차원 배열

```javascript
# 10부터 19까지 연속적인 수로 이루어진 'arr2'라는 배열
# shape: 1차원 배열
arr2 = np.arange(10, 20)
arr2

# index가 4부터 6까지인 원소 출력
arr2[4:7]

# index가 6 이상인 원소 출력
arr2[6:]

# index가 6 이상인 원소를 모두 20으로 바꾸기
arr2[6:] = 20
arr2
```

- 다차원 배열

```javascript
# 1부터 9까지 연속적인 수로 이루어진 'arr3'라는 배열
# shape: 3X3인 2차원 배열
arr3 = np.arange(1, 10).reshape(3, 3)
arr3

# 2, 3, 5, 6으로 구성된 2차원 배열 출력
arr3[:2, 1:]

# 1행과 2행 출력
arr3[:2]

# 2열 출력
arr3[:,1]

# 2, 3, 5, 6을 모두 결측치로 바꾸기
# 결측치: 데이터에 값이 없는 것 (NaN, null, None)
# 결측치 != 0, False
arr3[:2, 1:] = np.nan
arr3

# numpy에서 자료형이 float일 때만 결측치 삽입 가능
arr3 = arr3.astype('float')
arr3[:2, 1:] = np.nan
arr3
```

### 마스킹 연산 (boolean 인덱싱)

조건에 부합하는 데이터만 추출하는 방법

```javascript
# 난수가 표준정규분포 따르는 'arr4'라는 배열 생성
# shape: 5X5인 2차원 배열
arr4 = np.random.randn(5, 5)
arr4

# arr4 안의 원소가 양수이면 True, 음수이면 False 출력
arr4 > 0

# arr4 안의 원소가 음수면 0 삽입
arr4[arr4 < 0] = 0
arr4
```

For the site tree, see the [root Markdown](https://slashpage.com/yerim-devnote.md).
