02. NumPy: 파이썬 위의 C언어
"반복문(for)을 쓰는 순간, 이미 느린 것입니다. 데이터를 한 번에 밀어넣으세요."
NumPy(Numerical Python)는 파이썬 데이터 과학의 심장입니다. 겉모습은 배우기 쉬운 파이썬이지만, 알맹이는 C언어로 최적화되어 있습니다.
개발자가 파이썬 문법으로 명령을 내리면, 실제 계산은 C언어가 빛의 속도로 처리하고 결과만 돌려줍니다. 이것이 파이썬이 느리다는 편견을 깨고 AI 언어가 된 비결입니다.
1. 벡터화 연산 (Vectorization): for 문을 버려라
리스트로 숫자 100만 개에 2를 곱하려면 for 문을 100만 번 돌려야 합니다. NumPy는 이 과정을 단 한 줄로 처리합니다.
- 기존 방식 (Scalar): "하나 꺼내서 곱하고, 다음 거 꺼내서 곱하고..." (직렬 처리)
- 벡터화 방식 (Vector): "야, 여기 있는 숫자 전체에 2를 곱해!" (병렬 처리)
import numpy as np
# 리스트: 반복문 필요
my_list = [1, 2, 3]
new_list = []
for x in my_list:
new_list.append(x * 2)
# NumPy: 압도적인 단순함
my_arr = np.array([1, 2, 3])
new_arr = my_arr * 2 # [2, 4, 6] -> 끝!
graph LR
subgraph Loop["기존 Loop 방식"]
direction TB
A1[1] --> |x2| B1[2]
A2[2] --> |x2| B2[4]
A3[3] --> |x2| B3[6]
style A1 fill:#eee
style B1 fill:#eee
end
subgraph Vector["NumPy 벡터화"]
direction TB
arr["[1, 2, 3]"]
op{{"x 2"}}
res["[2, 4, 6]"]
arr ===> op ===> res
end
style Vector fill:#e1f5fe,stroke:#01579b
style op fill:#ffecb3,stroke:#ff6f00
2. 브로드캐스팅 (Broadcasting): 융통성 있는 계산
수학에서는 원래 행렬끼리 모양(Shape)이 같아야 계산이 됩니다. 하지만 NumPy는 모양이 달라도 알아서 늘려서(Broadcast) 계산해줍니다.
- 상황:
[1, 2, 3](3칸) +10(1칸) - NumPy의 마법:
10을 자동으로[10, 10, 10]으로 복사해서 계산합니다.
graph TD
subgraph Original["원본 데이터"]
Row1["[ 1, 2, 3 ]"]
Plus{"+"}
Single["10"]
end
subgraph Broadcast["브로드캐스팅 (자동 확장)"]
B_Row1["[ 1, 2, 3 ]"]
B_Plus{"+"}
B_Single["[ 10, 10, 10 ]"]
end
Original --> |NumPy가 알아서 변환| Broadcast
style Broadcast fill:#e1f5fe,stroke:#01579b
style B_Single fill:#ffccbc,stroke:#d84315
3. 차원 (Dimension): 데이터를 보는 눈
AI 데이터는 복잡합니다. 이를 다루기 위해선 차원(Dimension) 개념이 필수입니다. NumPy에서는 .ndim과 .shape으로 이를 확인합니다.
| 차원 | 이름 (수학/전산) | 코드 예시 (np.array) |
비유 |
|---|---|---|---|
| 0D | Scalar (스칼라) | 10 |
점 하나 |
| 1D | Vector (벡터) | [1, 2, 3] |
선 (한 줄 서기) |
| 2D | Matrix (행렬) | [[1, 2], [3, 4]] |
면 (엑셀 표, 흑백 사진) |
| 3D | Tensor (텐서) | [[[1], [2]], ...] |
입체 (컬러 사진, 동영상) |
import numpy as np
# 1D Vector (1차원)
vector = np.array([1, 2, 3])
print(f"Vector: 차원={vector.ndim}, 모양={vector.shape}")
# 결과: Vector: 차원=1, 모양=(3,)
# 2D Matrix (2차원)
matrix = np.array([[1, 2, 3],
[4, 5, 6]])
print(f"Matrix: 차원={matrix.ndim}, 모양={matrix.shape}")
# 결과: Matrix: 차원=2, 모양=(2, 3) -> 2행 3열
설계자의 시선: Shape이 전부다
딥러닝 모델을 만들 때 에러의 90%는 이 모양(Shape)이 안 맞아서 터집니다.
- "3x4 행렬과 5x2 행렬은 곱할 수 없어!"
데이터의 값(Value)보다 데이터의 형태(Shape)와 차원(Dimension)을 꿰뚫어 보는 눈을 길러야 합니다. NumPy는 이 훈련을 위한 최고의 도구입니다.
4. NumPy 유니버스 (Ecosystem)
"NumPy만 알면, 파이썬 데이터 생태계의 시민권을 얻는 셈입니다."
NumPy는 혼자 쓰이기보다, 다른 거대한 라이브러리들의 '기반(Foundation)'으로 쓰일 때 더 빛납니다. 말씀하신 SciPy나 Scikit-learn도 결국 내부적으로는 NumPy 배열을 주고받습니다.
- SciPy (Science): 미적분, 신호 처리 등 '고급 과학 계산' 담당. (NumPy + 과학 공식)
- Scikit-learn (Machine Learning): '전통적인 머신러닝' (회귀, 분류, 클러스터링) 담당. (NumPy + 통계 알고리즘)
- TensorFlow / PyTorch (Deep Learning): '인공신경망' 담당. (NumPy + GPU 가속)
graph TD
NumPy[("NumPy (Foundation)<br>핵심 데이터 구조")]
SciPy["SciPy<br>(과학 계산)"]
Sklearn["Scikit-learn<br>(머신러닝)"]
Pandas["Pandas<br>(데이터 분석)"]
Stats["통계/최적화"]
Model["AI 모델 학습"]
Clean["데이터 전처리"]
SciPy --> NumPy
Sklearn --> NumPy
Pandas --> NumPy
Stats -.-> SciPy
Model -.-> Sklearn
Clean -.-> Pandas
style NumPy fill:#ffecb3,stroke:#ff6f00,stroke-width:4px
style SciPy fill:#e1f5fe,stroke:#01579b
style Sklearn fill:#e1f5fe,stroke:#01579b
style Pandas fill:#e1f5fe,stroke:#01579b
이제 숫자는 엑셀처럼 표로 정리는 했는데, "이 숫자가 무슨 뜻인지" 알 수가 없죠? 이름표를 붙일 차례입니다. 다음 챕터 Pandas로 넘어갑니다.