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

Python pandas读取大型CSV文件时如何添加进度条?

大CSV文件读取添加进度条解决方案

核心思路是利用pandas原生分块读取能力配合tqdm实现进度跟踪,不改变原有读取逻辑,性能损耗极低。

依赖导入

import pandas as pd
import numpy as np
from tqdm import tqdm

辅助工具函数

用于提前统计文件总行数,计算进度条总长度:

def get_file_total_lines(filepath: str, encoding: str = 'iso-8859-1') -> int:
    """统计CSV文件总行数,用于计算读取进度"""
    with open(filepath, 'r', encoding=encoding) as f:
        return sum(1 for _ in f)

修改后的完整读取函数

仅替换原有全量读取逻辑,其余业务规则完全保留:

def read_from_csv(filepath: str,
                  sep: str = ",",
                  header_line: int = 43,
                  skip_rows: int = 48,
                  chunk_size: int = 100000) -> pd.DataFrame:
    """Reads a csv file at filepath containing the vehicle trip data and 
    performs a number of formatting operations
    """
    
    # 第一次调用read_csv用于获取列名,让第二次读取时就能完成类型指定,比后续强制转换类型效率更高
    df_names: pd.Index[str] = pd.read_csv(
                            filepath,
                            sep = sep,
                            header = header_line,
                            skip_blank_lines = False,
                            skipinitialspace = True,
                            index_col = False,
                            engine = 'c',
                            nrows = 0,
                            encoding = 'iso-8859-1'
    ).columns

    # "Time"和"Time_abs"列的实际名称前会有不一致的"存储组代码"前缀,因此先存储完整列名供后续重命名使用;同时我们需要将"Time_abs"识别为字符串类型,其余列识别为浮点型,该配置存入字典供第二次read_csv调用使用
    time_col =      ""
    time_abs_col =  ""
    names_dict = {}
    for name in df_names:
        if ": Time_abs" in name:
            names_dict[name] = 'str'
            time_abs_col = name
        elif ": Time" in name:
            time_col = name
        else:
            names_dict[name] = 'float'

    
    # 需要被pandas识别为空值的取值列表,其中只有"NOVALUE"是文件中实际会出现的取值,其余为默认缺省值
    na_vals = ['', '#N/A N/A', '#NA', '-1.#IND', '-1.#QNAN', '-NaN', '-nan',
               '1.#IND', '1.#QNAN', '<NA>', 'N/A', 'NA', 'NULL', 'NaN', 'n/a',
               'nan', 'null', 'NOVALUE']

    # 分块读取文件并展示进度条
    total_valid_lines = get_file_total_lines(filepath) - skip_rows
    chunks = []
    with tqdm(total=total_valid_lines, unit='行', desc='CSV读取进度') as pbar:
        for chunk in pd.read_csv(filepath,
                                   sep = sep,
                                   skiprows = skip_rows,
                                   header = 0,
                                   names = df_names,
                                   skip_blank_lines = False,
                                   skipinitialspace = True,
                                   index_col = False,
                                   engine = 'c',
                                   na_values = na_vals,
                                   dtype = names_dict,
                                   encoding = 'iso-8859-1',
                                   chunksize=chunk_size
                                   ):
            chunks.append(chunk)
            pbar.update(len(chunk))
    df = pd.concat(chunks, ignore_index=True)

    
    # 重命名"Time"和"Time_abs"列,移除前缀的存储组标识
    df.rename(columns = {time_col: "Time", time_abs_col: "Time_abs"}, 
              inplace = True)

    # 第二次调整该列类型,从字符串转为datetime类型;极少数情况下CSV中的Time_abs列只有时间没有日期,会触发报错,此时直接保留字符串类型即可
    try:
        df[defs.time_abs] = pd.to_datetime(df[defs.time_abs])
    except:
        pass

    
    # 每行末尾的多余分隔符会被识别为一个空列,在此处删除,避免调试时产生混淆
    df.drop(df.columns[-1], axis=1, inplace=True)

    # 为后续处理添加额外列
    df[defs.lowest_gear] = np.nan
    df[defs.lowest_speed] = np.nan
    for i in list(defs.second_trailer_axles_dict.values()):
        df[i] = np.nan

    return df

注意事项

  • 可根据本机内存大小调整chunk_size参数,数值越大读取速度越快、内存占用越高,默认10万行适配大多数场景
  • 统计文件行数的编码必须和读取CSV的编码保持一致,避免编码报错
  • 进度条默认按行统计,可直观展示已读行数和预估剩余时间

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 19:54:02