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

如何从多个2000万行制表符分隔文件各采样2万行合并为Pandas DataFrame

嘿,这个需求我太熟悉了——直接加载2000万条记录的文件绝对会把内存撑爆,必须用高效的逐文件抽样策略才行。下面给你一套完整的实现方案,分步骤来:

核心思路

我们的目标是不加载整个文件,只抽取每个文件中的2万条随机记录,最后合并成一个DataFrame。主要有两种可靠的实现方式,你可以根据自己的内存情况选择:


方法一:先算总行数,跳过不需要的行

这种方法适合文件行数能快速计算的场景,效率很高:

步骤1:导入必要的库

import pandas as pd
import os
import random

步骤2:编写单个文件的抽样函数

这个函数会先统计文件的总行数,然后随机生成要跳过的行号,只读取我们需要的2万条:

def sample_large_tsv(file_path, sample_size=20000):
    # 统计文件总行数(减去表头行)
    with open(file_path, 'r', encoding='utf-8') as f:
        total_data_rows = sum(1 for _ in f) - 1  # 表头占1行,剩下的是数据行
    
    # 生成需要跳过的行号:总行数 - 抽样数 = 要跳过的行数
    # 注意:read_csv的skiprows是跳过的行索引(从0开始,0是表头),所以数据行是1到total_data_rows
    skip_indices = random.sample(range(1, total_data_rows + 1), total_data_rows - sample_size)
    
    # 读取文件,只保留抽样行
    sampled_df = pd.read_csv(
        file_path,
        sep='\t',
        skiprows=skip_indices,
        low_memory=False  # 关闭内存优化,避免大文件的类型推断警告
    )
    return sampled_df

步骤3:遍历文件夹并合并结果

# 替换成你的文件夹路径
target_folder = "/your/folder/path/with/tsv/files"
sampled_dfs = []

# 遍历所有tsv文件
for file_name in os.listdir(target_folder):
    if file_name.lower().endswith(".tsv"):
        full_path = os.path.join(target_folder, file_name)
        print(f"正在处理文件: {file_name}")
        # 调用抽样函数
        df = sample_large_tsv(full_path)
        sampled_dfs.append(df)

# 合并所有抽样数据
final_combined_df = pd.concat(sampled_dfs, ignore_index=True)

# 验证结果
print(f"合并完成!总记录数: {len(final_combined_df)}")

方法二:分块读取抽样(更适合超大型文件)

如果你的内存特别紧张,或者文件行数统计很慢,可以用分块读取的方式,每次读一部分数据并抽样,直到凑够2万条:

def sample_tsv_by_chunks(file_path, sample_size=20000, chunk_size=100000):
    sampled_chunks = []
    collected = 0
    
    # 分块读取文件
    for chunk in pd.read_csv(
        file_path,
        sep='\t',
        chunksize=chunk_size,
        low_memory=False
    ):
        if collected >= sample_size:
            break
        # 计算当前块需要抽多少条
        need = sample_size - collected
        # 从当前块中随机抽样
        chunk_sample = chunk.sample(n=min(need, len(chunk)), random_state=42)
        sampled_chunks.append(chunk_sample)
        collected += len(chunk_sample)
    
    return pd.concat(sampled_chunks, ignore_index=True)

使用的时候只需要把步骤3里的sample_large_tsv换成这个函数就行。


关键注意事项

  • 可复现性:如果需要每次抽样结果一致,给random.sample或者chunk.sample加上random_state参数(比如random_state=42)。
  • 内存优化:可以给read_csv指定dtype参数,比如dtype={"user_id": "int32", "category": "category"},大幅减少内存占用。
  • 编码问题:如果文件不是UTF-8编码,记得修改encoding参数(比如encoding="gbk")。
  • 表头一致性:确保所有文件的表头完全相同,否则合并时会出现列不匹配的问题。如果表头不一致,先统一表头再抽样。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 09:13:40