sample()做简单随机采样时,n与frac互斥,需根据需求选其一;分层采样须用train_test_split(stratify=y);bootstrap需设replace=true;大规模数据可用skiprows随机跳行。

用 sample() 做简单随机采样,但要注意 frac 和 n 互斥
直接调用 df.sample() 是最常用方式,但它有两个核心参数不能同时设值:n 指定行数,frac 指定比例。设了 n=100 再设 frac=0.1 会报 ValueError: Cannot specify both 'n' and 'frac'。
常见错误是想“取 10% 数据且至少 50 行”,结果硬写两者——得先判断 len(df) * 0.1 是否 ≥ 50,再选 n 或 frac。
- 要固定行数(比如每次训练都用 1000 行):用
df.sample(n=1000, random_state=42) - 要按比例(比如留 20% 做验证):用
df.sample(frac=0.2, random_state=42) - 必须带
random_state,否则每次运行结果不同,无法复现实验
分层采样要用 sklearn.model_selection.train_test_split,不是 sample()
sample() 是纯随机,对类别不均衡数据(比如欺诈检测中 99% 正常、1% 欺诈)会大概率漏掉少数类。这时候得用分层抽样,保证训练集里各类比例和原数据一致。
别试图用 groupby().apply(lambda x: x.sample(...)) 手动分层——容易漏掉空组、打乱索引、丢失原始列结构,还慢。
- 正确做法:用
train_test_split(X, y, stratify=y, test_size=0.2, random_state=42) -
stratify=y是关键,y必须是一维数组或 Series,不能是 DataFrame 的一列(得写成df['label'],不是df[['label']]) - 如果原始
df有索引,train_test_split返回的X_train索引会重排,需要保留原始索引时加shuffle=False并手动处理
重复采样(bootstrap)要显式设 replace=True,默认是不放回
默认 df.sample() 是不放回抽样,即每行最多出现一次。做 bagging 或评估模型稳定性时需要有放回抽样(bootstrap),必须加 replace=True,否则样本量会受限于原数据长度。
例如 df.sample(n=1000, replace=False) 在原数据只有 800 行时会直接报错;而 replace=True 就能成功,但要注意同一行可能被多次抽中。
- 检查是否启用放回:打印
len(df_sample)和len(df_sample.drop_duplicates()),二者不等说明有重复 - 如果后续要 merge 回原表做分析,重复索引会导致
merge出现意外多行,建议采样后重置索引:df.sample(...).reset_index(drop=True) -
replace=True时random_state依然有效,可复现相同重复模式
大规模数据下避免全量加载,用 pd.read_csv(..., skiprows=...) 配合随机跳行
当 CSV 有千万行,内存装不下,又不想用 Dask 或 Vaex 这类额外依赖时,sample() 就没法用了——它得先把整个文件读进内存。
可行替代方案是估算总行数后,随机生成若干行号,用 skiprows 跳过不需要的行。虽然不严格等概率(首尾行偏差略大),但对训练影响通常可接受。
- 先用
wc -l file.csv或 Python 的sum(1 for _ in open('file.csv'))获取总行数N - 生成随机行号列表:
rows = sorted(random.sample(range(1, N), k=10000))(跳过 header 行) - 读取时:
pd.read_csv('file.csv', skiprows=lambda x: x not in rows) - 注意:该方法在 Windows 上对大文件可能较慢,且无法保证 header 被跳过——建议先用
header=0显式指定,再让skiprows从第 1 行开始算
实际应用里,多数时候 sample() + train_test_split 组合就够用;真正卡住你的往往不是函数怎么写,而是忘了 random_state、误用 frac 和 n、或者在类别不平衡时硬上简单随机。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











