C.W.K.
Stream
Lesson 06 of 06 · published

코드에서 벡터 연산: 영원히 재사용할 패턴

~10 min · numpy, pytorch, broadcasting, operations

Level 0수학 초심자
0 XP0/59 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete

다섯 패턴

AI 에서 거의 모든 벡터 코드 조각이 이 다섯 중 하나. 시각으로 알면 읽기 시간 엄청 절약.

  1. Element-wise opa + b, a * b, np.exp(a). 같은 모양 in, 같은 모양 out.
  2. Reductiona.sum(), a.mean(), a.max(). 많은 게 in, 하나 (또는 적게) out. axis= 선택 지정.
  3. 내적 / 행렬곱a @ b. 두 벡터 → 스칼라. 벡터+행렬 → 벡터. 두 행렬 → 행렬.
  4. Broadcasting — 다른 모양 배열에 작업, 하나가 매치 위해 "올라감". matrix + vector 가 종종 그냥 됨.
  5. Slicing / fancy 인덱싱a[2:5], a[a > 0], a[indices]. 루프 없이 부분집합 뽑기.

30초 broadcasting

NumPy/PyTorch 가 (3,) 벡터를 (4, 3) 행렬에 더하게 해줘 — 벡터가 각 행에 broadcast. 룰: 차원이 같거나 한 쪽이 1 일 때 호환. 오른쪽부터 정렬. 룰 실패 = 전설의 shapes ... not aligned 에러.

배열 element 위로 루프 작성 멈춰. for i in range(len(arr)) 자신이 쓰고 있으면 물어: vectorized 버전 있나? 95% 경우 yes — 그리고 10-1000배 빨라.

트랙 보상

이제 벡터로 사고. 크기 × 방향 = 단위. 내적 = 정렬-숫자. Norm = 고를 수 있는 자. 연산 vectorize. 여기서부터 행렬은 함께 작동하는 벡터 stack — 다음 트랙.

Code

다섯 패턴 15줄에·python
import numpy as np

a = np.array([1, 2, 3, 4])
b = np.array([10, 20, 30, 40])

# Element-wise
print(a + b)                         # [11 22 33 44]
print(a * b)                         # [10 40 90 160]

# Reduction
print(a.sum(), a.mean(), a.max())    # 10  2.5  4

# Broadcasting
M = np.array([[1, 2, 3, 4],
              [5, 6, 7, 8]])
print(M + a)                         # 벡터가 행에 broadcast
# [[ 2  4  6  8]
#  [ 6  8 10 12]]

# Fancy 인덱싱
mask = a > 2
print(a[mask])                       # [3 4]
MLX flavor — Apple Silicon, NumPy 모양 그대로·python
import mlx.core as mx

# 같은 패턴 — Apple Silicon GPU 에서 Metal 통해 돌아감, .to(device) X
a = mx.array([1, 2, 3, 4])
b = mx.array([10, 20, 30, 40])

print(a + b)                         # [11, 22, 33, 44]
print((a * b).sum().item())          # 1000

M = mx.array([[1, 2, 3, 4],
              [5, 6, 7, 8]])
print(M + a)                         # (4,) 벡터를 행에 broadcast

# MLX 는 lazy — 실제로 evaluate 될 때 출력. 루프에선 mx.eval(...) 로
# 강제 materialize.

External links

Exercise

명시적 for 루프 없이: (5, 3) 임의 float 행렬, 열 평균 빼고, 열 std 로 나눠 (= 열별 z-score 표준화). 결과 열들의 평균 ≈ 0, std ≈ 1 확인.
Hint
(M - M.mean(axis=0)) / M.std(axis=0). axis=0 이 행 가로질러 축소, (3,) 벡터 남기고 행에 다시 broadcast.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고
💛 by 피파happy

댓글 2

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.
  1. Elechemist
    Elechemist

    just do it 정신을 잠시 잃고 너무 오랜만에 돌아왔어 , 평균 0 , 표준편차 1 인거 확인!

    import numpy as np

    rng = np.random.default_rng(42) X = rng.standard_normal((5, 3))

    mu = X.mean(axis=0) sigma = X.std(axis=0)

    Z = (X - mu) / sigma

    print("열 평균:", Z.mean(axis=0)) print("열 std :", Z.std(axis=0))

    assert np.allclose(Z.mean(axis=0), 0, atol=1e-12) assert np.allclose(Z.std(axis=0), 1, atol=1e-12) print("검증 통과")

    💛 by 피파happy
    1. 피파
      피파· happyElechemistElechemist

      Elechemist님, 돌아온 것 자체가 이미 just do it 재가동이에요. 코드도 정확해요 — axis=0으로 열별 평균/std를 만들고, 그 (3,) 벡터가 다시 각 행에 broadcast되면서 Z-score가 된 구조까지 잘 잡으셨어요. 다음엔 같은 패턴을 torchmlx로 한 번만 옮겨보면 “NumPy 문법”이 아니라 “배열 사고방식”이라는 게 더 선명해질 거예요.