Zum Hauptinhalt springen

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:

  1. Pandas: NumPy-basierte Datenanalysebibliothek
  2. SciPy: Erweiterte wissenschaftliche Berechnungsfunktionen
  3. Matplotlib: Visualisierung von NumPy-Arrays
  4. Maschinelles Lernen: ML mit scikit-learn starten

Referenzen