You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:从无法用Pandas直接导入的1.6亿行CSV抽取5%随机样本

超大CSV文件的随机抽样解决方案

方法1:Shell命令快速抽样(推荐,性能最优)

Linux/macOS下直接用系统级工具处理,无需加载整个文件到内存,速度最快:

精确抽取800万行(含表头)

先统计总行数(扣除表头),再用shuf随机抽取:

# 获取总行数(减去1行表头)
total_data_lines=$(($(wc -l < input.csv) - 1))
# 先写入表头
head -n 1 input.csv > sample.csv
# 从数据行中随机抽取800万行追加到样本文件
shuf -n 8000000 <(tail -n +2 input.csv) >> sample.csv

按5%概率抽样(无需提前统计行数)

用awk生成随机数,每行有5%概率被选中,结果接近目标样本量:

# 写入表头
head -n 1 input.csv > sample.csv
# 遍历数据行,按概率抽样
awk 'BEGIN{srand()} NR>1 {if(rand()<=0.05) print}' input.csv >> sample.csv

方法2:Python csv模块逐行处理(内存占用极低)

适合需要自定义逻辑的场景,逐行读取文件,内存占用仅为单行列数据大小:

概率抽样版本

import csv
import random

random.seed(42)  # 固定随机种子,保证抽样结果可复现

with open('input.csv', 'r', newline='') as infile, open('sample.csv', 'w', newline='') as outfile:
    reader = csv.reader(infile)
    writer = csv.writer(outfile)
    
    # 写入表头
    writer.writerow(next(reader))
    
    # 逐行判断是否抽样
    for row in reader:
        if random.random() <= 0.05:
            writer.writerow(row)

精确抽取800万行版本

先统计总行数,再生成随机行号集合,精准抽取目标行数:

import csv
import random

# 统计数据总行数(跳过表头)
with open('input.csv', 'r') as f:
    total_data_lines = sum(1 for _ in f) - 1

# 生成要抽取的随机行号(对应数据行,从1开始计数)
target_rows = set(random.sample(range(1, total_data_lines + 1), 8000000))

with open('input.csv', 'r', newline='') as infile, open('sample.csv', 'w', newline='') as outfile:
    reader = csv.reader(infile)
    writer = csv.writer(outfile)
    
    writer.writerow(next(reader))  # 写入表头
    
    current_line = 0
    for row in reader:
        current_line += 1
        if current_line in target_rows:
            writer.writerow(row)

方法3:改进Pandas分块抽样(适配后续Pandas分析)

如果之前用chunksize失败,大概率是没有分块写入文件导致内存溢出。试试分块处理后直接追加到文件,避免内存累积:

import pandas as pd

chunk_size = 200000  # 根据你的内存情况调整,比如20万行/块
is_first_chunk = True

for chunk in pd.read_csv('input.csv', chunksize=chunk_size):
    # 对当前块抽取5%样本
    chunk_sample = chunk.sample(frac=0.05, random_state=42)
    # 写入文件:第一块写表头,后续块跳过表头
    chunk_sample.to_csv(
        'sample.csv',
        mode='w' if is_first_chunk else 'a',
        header=is_first_chunk,
        index=False
    )
    is_first_chunk = False

这个方法的内存占用仅为单个chunk的大小,不会把所有样本都加载到内存中。

内容的提问来源于stack exchange,提问作者Marcelo Fernandes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 12:57:29