NumPy Grundlagen 📊
NumPy (Numerical Python) ist die Kernbibliothek für wissenschaftliches Rechnen in Python. Sie bietet leistungsstarke mehrdimensionale Array-Objekte und schnelle Rechenfunktionen.
Was ist NumPy?
NumPy unterstützt große mehrdimensionale Arrays und Matrixoperationen und enthält eine Bibliothek mathematischer Funktionen.
Hauptmerkmale
- Schnelle Leistung: In C implementiert, 10-100x schneller als reines Python
- Speichereffizienz: Verwendet zusammenhängende Speicherblöcke
- Broadcasting: Operationen zwischen Arrays unterschiedlicher Größe möglich
- Vektorisierung: Operationen auf ganzen Arrays ohne Schleifen
Installation
pip install numpy
import numpy as np
# 버전 확인
print(np.__version__) # 1.24.3
ndarray erstellen
Grundlegende Erstellungsmethoden
import numpy as np
# 리스트에서 생성
arr1 = np.array([1, 2, 3, 4, 5])
print(arr1) # [1 2 3 4 5]
print(type(arr1)) # <class 'numpy.ndarray'>
# 2차원 배열
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
print(arr2)
# [[1 2 3]
# [4 5 6]]
# 3차원 배열
arr3 = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
print(arr3.shape) # (2, 2, 2)
Spezielle Arrays erstellen
# 0으로 채워진 배열
zeros = np.zeros((3, 4))
print(zeros)
# [[0. 0. 0. 0.]
# [0. 0. 0. 0.]
# [0. 0. 0. 0.]]
# 1로 채워진 배열
ones = np.ones((2, 3))
print(ones)
# [[1. 1. 1.]
# [1. 1. 1.]]
# 특정 값으로 채우기
full = np.full((2, 2), 7)
print(full)
# [[7 7]
# [7 7]]
# 단위 행렬
identity = np.eye(3)
print(identity)
# [[1. 0. 0.]
# [0. 1. 0.]
# [0. 0. 1.]]
# 범위 배열
range_arr = np.arange(0, 10, 2)
print(range_arr) # [0 2 4 6 8]
# 균등 간격 배열
linspace = np.linspace(0, 1, 5)
print(linspace) # [0. 0.25 0.5 0.75 1. ]
# 랜덤 배열
random_arr = np.random.rand(3, 3) # 0~1 사이 균등 분포
print(random_arr)
random_int = np.random.randint(1, 100, size=(3, 3)) # 정수 랜덤
print(random_int)
Array-Eigenschaften
arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
print(arr.shape) # (2, 4) - 배열의 형태
print(arr.ndim) # 2 - 차원 수
print(arr.size) # 8 - 전체 요소 개수
print(arr.dtype) # int64 - 데이터 타입
print(arr.itemsize) # 8 - 각 요소의 바이트 크기
Indizierung und Slicing
Eindimensionale Arrays
arr = np.array([10, 20, 30, 40, 50])
print(arr[0]) # 10 - 첫 번째 요소
print(arr[-1]) # 50 - 마지막 요소
print(arr[1:4]) # [20 30 40] - 슬라이싱
print(arr[::2]) # [10 30 50] - 2칸씩 건너뛰기
print(arr[::-1]) # [50 40 30 20 10] - 역순
Zweidimensionale Arrays
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(arr[0, 0]) # 1 - 첫 번째 행, 첫 번째 열
print(arr[1, 2]) # 6 - 두 번째 행, 세 번째 열
print(arr[0]) # [1 2 3] - 첫 번째 행 전체
print(arr[:, 1]) # [2 5 8] - 두 번째 열 전체
print(arr[0:2, 1:3]) # [[2 3] [5 6]] - 부분 배열
Bedingte Indizierung
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
# 조건을 만족하는 요소만 선택
print(arr[arr > 5]) # [6 7 8 9 10]
print(arr[arr % 2 == 0]) # [2 4 6 8 10]
# 여러 조건
print(arr[(arr > 3) & (arr < 8)]) # [4 5 6 7]
Array-Operationen
Grundlegende arithmetische Operationen
arr1 = np.array([1, 2, 3, 4])
arr2 = np.array([10, 20, 30, 40])
print(arr1 + arr2) # [11 22 33 44]
print(arr1 - arr2) # [-9 -18 -27 -36]
print(arr1 * arr2) # [10 40 90 160]
print(arr1 / arr2) # [0.1 0.1 0.1 0.1]
print(arr1 ** 2) # [1 4 9 16]
# 스칼라 연산
print(arr1 + 10) # [11 12 13 14]
print(arr1 * 2) # [2 4 6 8]
Mathematische Funktionen
arr = np.array([1, 4, 9, 16])
print(np.sqrt(arr)) # [1. 2. 3. 4.]
print(np.exp(arr)) # 지수 함수
print(np.log(arr)) # 자연 로그
print(np.sin(arr)) # 삼각 함수
# 최대/최소
arr = np.array([3, 1, 4, 1, 5, 9, 2, 6])
print(np.max(arr)) # 9
print(np.min(arr)) # 1
print(np.argmax(arr)) # 5 - 최댓값의 인덱스
print(np.argmin(arr)) # 1 - 최솟값의 인덱스
Broadcasting
Broadcasting verarbeitet automatisch Operationen zwischen Arrays unterschiedlicher Größe.
# 1차원 배열 + 스칼라
arr = np.array([1, 2, 3])
print(arr + 5) # [6 7 8]
# 2차원 배열 + 1차원 배열
arr2d = np.array([[1, 2, 3], [4, 5, 6]])
arr1d = np.array([10, 20, 30])
print(arr2d + arr1d)
# [[11 22 33]
# [14 25 36]]
# 2차원 배열 + 열 벡터
arr2d = np.array([[1, 2, 3], [4, 5, 6]])
col_vec = np.array([[10], [20]])
print(arr2d + col_vec)
# [[11 12 13]
# [24 25 26]]
Aggregationsfunktionen
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(np.sum(arr)) # 21 - 전체 합
print(np.mean(arr)) # 3.5 - 평균
print(np.std(arr)) # 1.707... - 표준편차
print(np.var(arr)) # 2.916... - 분산
print(np.median(arr)) # 3.5 - 중앙값
# 축 지정
print(np.sum(arr, axis=0)) # [5 7 9] - 열 방향 합
print(np.sum(arr, axis=1)) # [6 15] - 행 방향 합
print(np.mean(arr, axis=0)) # [2.5 3.5 4.5] - 열 평균
print(np.mean(arr, axis=1)) # [2. 5.] - 행 평균
Array-Form ändern
arr = np.array([1, 2, 3, 4, 5, 6])
# reshape - 형태 변경
reshaped = arr.reshape(2, 3)
print(reshaped)
# [[1 2 3]
# [4 5 6]]
# flatten - 1차원으로 펼치기
flattened = reshaped.flatten()
print(flattened) # [1 2 3 4 5 6]
# transpose - 전치
arr2d = np.array([[1, 2, 3], [4, 5, 6]])
print(arr2d.T)
# [[1 4]
# [2 5]
# [3 6]]
# 차원 추가
arr = np.array([1, 2, 3])
expanded = np.expand_dims(arr, axis=0)
print(expanded.shape) # (1, 3)
Arrays kombinieren
arr1 = np.array([[1, 2], [3, 4]])
arr2 = np.array([[5, 6], [7, 8]])
# 수직 결합
vstack = np.vstack([arr1, arr2])
print(vstack)
# [[1 2]
# [3 4]
# [5 6]
# [7 8]]
# 수평 결합
hstack = np.hstack([arr1, arr2])
print(hstack)
# [[1 2 5 6]
# [3 4 7 8]]
# concatenate
concat = np.concatenate([arr1, arr2], axis=0) # 행 방향
print(concat)
Praktische Beispiele
Beispiel 1: Schülernotenstatistik
import numpy as np
# 학생 5명의 3과목 성적 (행: 학생, 열: 과목)
scores = np.array([
[85, 90, 78], # 학생 1
[92, 88, 95], # 학생 2
[78, 85, 80], # 학생 3
[95, 92, 88], # 학생 4
[88, 86, 92] # 학생 5
])
# 각 학생의 평균 점수
student_avg = np.mean(scores, axis=1)
print("학생별 평균:", student_avg)
# [84.33 91.67 81. 91.67 88.67]
# 각 과목의 평균 점수
subject_avg = np.mean(scores, axis=0)
print("과목별 평균:", subject_avg)
# [87.6 88.2 86.6]
# 전체 평균
total_avg = np.mean(scores)
print(f"전체 평균: {total_avg:.2f}") # 87.47
# 최고 점수와 학생
max_score = np.max(scores)
max_position = np.unravel_index(np.argmax(scores), scores.shape)
print(f"최고 점수: {max_score} (학생 {max_position[0]+1}, 과목 {max_position[1]+1})")
# 90점 이상 받은 횟수
high_scores = np.sum(scores >= 90)
print(f"90점 이상: {high_scores}회") # 6회
Beispiel 2: Matrixoperationen und Lineare Algebra
import numpy as np
# 행렬 곱셈
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
# 행렬 곱 (내적)
C = np.dot(A, B)
# 또는 C = A @ B
print("행렬 곱:")
print(C)
# [[19 22]
# [43 50]]
# 역행렬
inv_A = np.linalg.inv(A)
print("역행렬:")
print(inv_A)
# [[-2. 1. ]
# [ 1.5 -0.5]]
# 역행렬 검증
identity = A @ inv_A
print("A × A^(-1):")
print(np.round(identity, 2)) # 단위 행렬
# 고유값과 고유벡터
eigenvalues, eigenvectors = np.linalg.eig(A)
print("고유값:", eigenvalues)
print("고유벡터:")
print(eigenvectors)
# 행렬식
det = np.linalg.det(A)
print(f"행렬식: {det}") # -2.0
Beispiel 3: Gleitenden Durchschnitt berechnen
import numpy as np
# 주식 가격 데이터
prices = np.array([100, 102, 98, 105, 107, 103, 110, 108, 112, 115])
def moving_average(data, window_size):
"""이동 평균 계산"""
weights = np.ones(window_size) / window_size
return np.convolve(data, weights, mode='valid')
# 3일 이동 평균
ma_3 = moving_average(prices, 3)
print("3일 이동 평균:", np.round(ma_3, 2))
# 5일 이동 평균
ma_5 = moving_average(prices, 5)
print("5일 이동 평균:", np.round(ma_5, 2))
# 수익률 계산
returns = (prices[1:] - prices[:-1]) / prices[:-1] * 100
print("일일 수익률(%):", np.round(returns, 2))
Beispiel 4: Grundlagen der Bildverarbeitung
import numpy as np
# 간단한 이미지 (8x8 그레이스케일)
image = np.random.randint(0, 256, size=(8, 8))
print("원본 이미지:")
print(image)
# 이미지 반전
inverted = 255 - image
print("\n반전 이미지:")
print(inverted)
# 밝기 조정 (+50)
brightened = np.clip(image + 50, 0, 255)
print("\n밝게:")
print(brightened)
# 대비 증가 (×1.5)
contrasted = np.clip(image * 1.5, 0, 255).astype(np.uint8)
print("\n대비 증가:")
print(contrasted)
# 이진화 (임계값 128)
binary = np.where(image > 128, 255, 0)
print("\n이진화:")
print(binary)
Leistungsvergleich
import numpy as np
import time
# 순수 Python vs NumPy
size = 1000000
# Python 리스트
python_list = list(range(size))
start = time.time()
result = [x * 2 for x in python_list]
python_time = time.time() - start
# NumPy 배열
numpy_array = np.arange(size)
start = time.time()
result = numpy_array * 2
numpy_time = time.time() - start
print(f"Python 리스트: {python_time:.4f}초")
print(f"NumPy 배열: {numpy_time:.4f}초")
print(f"NumPy가 {python_time/numpy_time:.1f}배 빠름")
Häufig gestellte Fragen
Was ist der Unterschied zwischen NumPy-Arrays und Python-Listen?
NumPy-Arrays:
- Speichern nur Daten desselben Typs
- Speichereffizient
- Schnelle Operationen (in C implementiert)
- Unterstützen vektorisierte Operationen
Python-Listen:
- Können verschiedene Typen mischen
- Einfache dynamische Größenanpassung
- Langsame Operationen (reines Python)
Was ist der Unterschied zwischen axis=0 und axis=1?
arr = np.array([[1, 2, 3], [4, 5, 6]])
# axis=0: 행 방향 (↓)
print(np.sum(arr, axis=0)) # [5 7 9]
# axis=1: 열 방향 (→)
print(np.sum(arr, axis=1)) # [6 15]
Was bedeutet -1 in reshape?
-1 bedeutet, die Größe automatisch zu berechnen.
arr = np.arange(12)
# 자동으로 4 계산
reshaped = arr.reshape(3, -1) # (3, 4)
# 자동으로 3 계산
reshaped = arr.reshape(-1, 4) # (3, 4)
# 1차원으로 펼치기
flattened = arr.reshape(-1) # (12,)
Kopie vs. Ansicht?
arr = np.array([1, 2, 3, 4, 5])
# 뷰 (원본 영향)
view = arr[1:4]
view[0] = 999
print(arr) # [1 999 3 4 5]
# 복사 (원본 안전)
copy = arr[1:4].copy()
copy[0] = 777
print(arr) # [1 999 3 4 5] (변경 없음)
Nächste Schritte
Wenn Sie NumPy beherrschen, lernen Sie als Nächstes:
- Pandas: NumPy-basierte Datenanalysebibliothek
- SciPy: Erweiterte wissenschaftliche Berechnungsfunktionen
- Matplotlib: Visualisierung von NumPy-Arrays
- Maschinelles Lernen: ML mit scikit-learn starten