NumPy 인덱싱은 3종류입니다 ① 기본 인덱싱/슬라이싱(view 반환), ② 불리언 마스킹(조건 필터링, copy 반환), ③ 팬시 인덱싱(정수 배열로 위치 지정, copy 반환).
전처리에서 가장 많이 쓰는 건 불리언 마스킹입니다 — "조건에 맞는 행만 골라서 값을 바꾸는" 작업이 전처리의 절반입니다.
import numpy as np다차원은 축을 콤마로 구분합니다. a[행, 열].
a = np.arange(1, 13).reshape(3, 4)
# [[ 1 2 3 4]
# [ 5 6 7 8]
# [ 9 10 11 12]]
a[0, 2] # 3 - 0행 2열 (스칼라)
a[1] # [5 6 7 8] - 1행 전체
a[:, 1] # [ 2 6 10] - 1열 전체 (모든 행의 1열)
a[0:2, 1:3] # [[2 3] - 0~1행 × 1~2열
# [6 7]]
a[-1] # [ 9 10 11 12] - 마지막 행
a[::2] # 0행, 2행 - 스텝 슬라이싱핵심: 슬라이싱 결과는 view입니다 (원본과 메모리 공유). 수정하면 원본이 바뀝니다.
row = a[0]
row[0] = 999
a[0, 0] # 999 ← 원본이 바뀜조건식은 불리언 배열을 만들고, 그것으로 인덱싱하면 True 위치의 원소만 뽑힙니다.
a = np.array([12, -3, 7, -8, 5])
a > 0 # array([ True, False, True, False, True])
a[a > 0] # array([12, 7, 5]) - True인 것만💡 이럴 때: 조건에 맞는 행만 골라 통계를 내거나 하위 집합을 추출할 때(특정 기간·그룹·임계값 필터).
and/or가 아니라 &/|파이썬의 and, or는 배열에서 동작하지 않습니다. 비트 연산자 &, |, ~를 쓰고, 각 조건을 괄호로 감쌉니다 (연산자 우선순위 때문).
a[(a > 0) & (a < 10)] # array([7, 5])
a[(a < 0) | (a > 10)] # array([12, -3, -8])
a[~(a > 0)] # array([-3, -8]) - 부정마스크를 대입의 왼쪽에 두면, 해당 위치만 값이 바뀝니다.
a = np.array([12, -3, 7, -8, 5])
a[a < 0] = 0 # 음수를 0으로
a # array([12, 0, 7, 0, 5])이것이 "이상치를 0으로", "결측을 평균으로" 같은 전처리의 기본 문법입니다.
💡 이럴 때: 음수 거래액을 0으로, 센서 오류값을 결측으로 바꾸는 등 "조건에 맞는 값만" 정제할 때 씁니다.
정수 리스트/배열을 인덱스로 주면, 그 순서대로 원소를 뽑습니다.
a = np.array([10, 20, 30, 40, 50])
a[[0, 2, 4]] # array([10, 30, 50])
a[[4, 4, 0]] # array([50, 50, 10]) - 중복·순서 자유
a[[0, 2, 4]] = -1 # 해당 위치 일괄 변경 → array([-1, 20, -1, 40, -1])2차원에서 행·열 인덱스를 각각 배열로 주면 좌표쌍으로 해석됩니다.
m = np.arange(1, 13).reshape(3, 4)
m[[0, 1, 2], [0, 1, 2]] # array([ 1, 6, 11]) - (0,0), (1,1), (2,2)반복문 없이 "조건에 따라 다른 값"을 만들 때 씁니다.
a = np.array([12, -3, 7, -8, 5])
np.where(a > 0, a, 0) # 조건 True→a, False→0 : array([12, 0, 7, 0, 5])
np.where(a > 0, 'pos', 'neg') # 문자열도 가능
np.clip(a, 0, 10) # 하한 0, 상한 10으로 자름 : array([10, 0, 7, 0, 5])
np.select(
[a < 0, a > 10], # 조건 리스트 (앞에서부터 매칭)
['neg', 'big'], # 각 조건에 대응하는 값
default='mid',
) # array(['big','neg','mid','neg','mid'])💡 이럴 때:
np.where(조건, x, y)는 결측을 대체값으로 채우거나 파생 변수(양수면 1)를 만들 때,np.clip은 이상치를 삭제 없이 상·하한으로 눌러 입력 분포를 안정화할 때(winsorizing) 씁니다.
np.where(조건, x, y): 삼항 연산자의 벡터화 버전입니다.np.clip(a, lo, hi): 이상치 처리에 자주 씁니다. np.where로도 되지만 clip이 명확합니다.np.select: if / elif / else의 벡터화입니다.함정: 아래 두 줄은 결과가 다릅니다.
a[a > 0] += 1 # OK - 원본의 양수들이 +1 (in-place 문법으로 인식됨)
b = a[a > 0] # b는 copy
b += 1 # a는 그대로, b만 바뀜전처리에서 "필터링한 결과를 수정했는데 원본에 반영이 안 된다"면 대개 이 문제입니다.
댓글
GitHub 계정으로 의견이나 질문을 남길 수 있습니다.