DataFrame.sample() / Series.sample() 은 행 (또는 열) 을 랜덤으로 추출 하는 함수. EDA 빠른 확인, train/test split, bootstrap, imbalanced data 처리에 자주 사용.
사용 상황
상황
패턴
EDA 미리보기
df.sample(20)
비율로 분할
df.sample(frac=0.8)
전체 섞기 (shuffle)
df.sample(frac=1, random_state=42)
Bootstrap 신뢰 구간
replace=True
Stratified 샘플링
df.groupby('label').sample(n=N)
가중 샘플링
weights='컬럼'
기본 사용
df.sample(n=5) # 5 개 무작위df.sample(frac=0.1) # 10% 무작위df.sample(n=5, random_state=42) # 시드 고정 (재현 가능)df.sample(frac=1, random_state=42) # 전체 섞기 (shuffle)
n 과 frac 은 둘 중 하나만 지정.
주요 파라미터
파라미터
기본값
설명
n
-
추출 개수 (frac 과 상호 배타)
frac
-
비율 (0~1, 1 초과 시 replace=True 필요)
replace
False
복원 추출 여부
weights
None
가중치 (Series 또는 컬럼명)
random_state
None
시드 (int 또는 numpy Generator)
axis
0
0 = 행 샘플, 1 = 열 샘플
ignore_index
False
True 면 결과 index 를 0,1,… 로 재배치
샘플링 전략 시각화
flowchart LR
A["원본 DataFrame"] --> B["n: 개수 고정"]
A --> C["frac: 비율 지정"]
A --> D["replace=True: 복원 추출"]
A --> E["weights: 가중 샘플"]
B --> F["고정 N 개 행"]
C --> G["전체 비율 행"]
D --> H["같은 행 중복 가능"]
E --> I["가중치 높은 행 더 자주"]
random_state (재현성)
# 매번 다른 결과df.sample(n=5)# 시드 고정: 같은 결과df.sample(n=5, random_state=42)# numpy Generator 도 가능 (pandas 1.4+)import numpy as nprng = np.random.default_rng(42)df.sample(n=5, random_state=rng)
테스트, ML 실험에서 random_state 미지정은 재현 불가능.
복원 추출 (Bootstrap)
# Bootstrap 한 번: 원본과 같은 크기, 중복 허용boot = df.sample(n=len(df), replace=True, random_state=42)# 1000 번 bootstrap 으로 평균의 95% 신뢰 구간import numpy as npsamples = [ df.sample(frac=1, replace=True, random_state=i)['salary'].mean() for i in range(1000)]ci = np.percentile(samples, [2.5, 97.5])print(f'95% CI: {ci[0]:.0f} ~ {ci[1]:.0f}')
# 각 클래스에서 10% 씩df.groupby('label').sample(frac=0.1, random_state=42)
ignore_index
df.sample(n=10, ignore_index=True)# 결과 DataFrame 의 index 가 0, 1, ..., 9 로 재설정# 원래 index 불필요할 때 사용
imbalanced data 처리
# 다운샘플링: 다수 클래스를 소수 클래스 크기로 줄이기minority = df[df['label'] == 1]majority = df[df['label'] == 0].sample(n=len(minority), random_state=42)balanced = pd.concat([minority, majority]).sample(frac=1, random_state=42)# 업샘플링: 소수 클래스를 복원 추출로 늘리기oversampled = df[df['label'] == 1].sample( n=len(df[df['label'] == 0]), replace=True, random_state=42,)balanced2 = pd.concat([df[df['label'] == 0], oversampled])
열 샘플링
# axis=1: 열을 샘플링df.sample(n=3, axis=1) # 컬럼 3 개 랜덤 선택df.sample(frac=0.5, axis=1) # 컬럼의 50%
numpy 와의 비교
import numpy as np# numpy: index 만 얻고 df 에서 선택idx = np.random.choice(len(df), size=100, replace=False)df.iloc[idx]# pandas: 바로 DataFrame, index 보존df.sample(n=100)
pandas API 가 더 자연스럽고 원본 index 를 보존한다.
실전 패턴
EDA 빠르게
df.sample(20) # 20 행만 보면서 데이터 형태 확인df.sample(frac=0.01) # 1% 미리보기 (대용량 파일)
# 그룹마다 크기가 다를 때: 최대 N 개 (부족하면 있는 만큼)df.groupby('category').sample(n=50, replace=False, random_state=42)# 그룹 크기 < 50 이면 ValueError → replace=True 또는 min(n, len) 처리
함정
1. random_state 미지정
df.sample(n=5) # 매 실행마다 다른 결과df.sample(n=5, random_state=42) # 고정 결과
ML 실험, 테스트 코드에는 반드시 시드 지정.
2. frac > 1.0 은 replace=True 필요
df.sample(frac=2.0) # ValueErrordf.sample(frac=2.0, replace=True) # ✓ 복원 추출
# 그룹 크기 < n 이면 ValueErrordf.groupby('label').sample(n=100, random_state=42)# 해결: replace=True 또는 각 그룹 크기 확인 후 min 적용
5. weights 에 NaN 있으면 오류
# weights 컬럼에 NaN 있으면 ValueErrorw = df['weight'].fillna(0)df.sample(n=10, weights=w)
6. index 보존 vs ignore_index
result = df.sample(n=5)# result.index 는 원본 df 의 index 값들 → 역추적 가능# df.loc[result.index] 로 원본에서 같은 행 확인result_reset = df.sample(n=5, ignore_index=True)# 0,1,2,3,4 로 재설정 → 원본 추적 불가
💬 댓글