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

如何将pandas DataFrame每行写入固定位置文本文件并解决覆盖及优化问题

问题原因

你遇到的覆盖问题核心是f.seek(position)的偏移量是相对于整个文件的起始位置计算的,不是相对于当前行的起始位置。处理第二行及后续数据时,seek会回到文件前1842字节的区间,直接覆盖上一行的内容。

修复方案

最简单的方案是避免在文件流中反复seek,优先在内存中拼好完整的单行列数据,再一次性写入文件,既不会出错性能也更高:

import pandas as pd

# 预先计算全局固定参数,只计算一次
max_line_pos = estructura['POSICION FINAL'].max()
# 若结构表中POSICION FINAL是闭区间终点,行内容长度为max_line_pos+1(0到1841共1842个字符)
line_content_length = max_line_pos + 1
newline = b'\r\n'
# 预存字段配置,避免循环中反复遍历结构表
field_config = [
    (r['VARIABLE'], r['POSICION INICIAL'] - 1) 
    for _, r in estructura.iterrows()
]
# 预先把整个df转成字符串类型,只转一次
str_data = pickled_data.astype(str)

with open('test_conversion.txt', 'wb') as f:
    # 配置行缓冲,攒N行再写入减少IO,可根据内存调整大小
    buffer = []
    buffer_size = 1000
    # itertuples遍历比iloc/iterrows快5-10倍
    for row in str_data.itertuples(index=False):
        # 内存中初始化当前行的空字节数组
        line_bytes = bytearray(b' ' * line_content_length)
        for var_name, start_pos in field_config:
            # 取当前行对应字段的字节
            val = getattr(row, var_name).encode('latin-1')
            # 填到对应位置
            line_bytes[start_pos:start_pos + len(val)] = val
        # 加换行符
        line_bytes += newline
        buffer.append(line_bytes)
        # 缓冲满了一次性写入
        if len(buffer) >= buffer_size:
            f.writelines(buffer)
            buffer.clear()
    # 写入剩余不满缓冲的行
    if buffer:
        f.writelines(buffer)

上亿行数据优化建议

  • 内存优化:如果全量df无法装入内存,读pickle时用pd.read_pickle(路径, chunksize=10000)分块读取处理,不要一次性加载全量数据
  • 遍历效率:优先用itertuples遍历行,不要用iterrows或者逐行iloc,性能差距可达10倍以上
  • IO优化:调整缓冲大小到合适值(比如1000-10000行),减少磁盘IO次数,磁盘IO是整个流程的主要瓶颈
  • 预计算:所有固定参数(结构配置、换行符、行长度等)都在循环外预计算,不要在循环内部重复计算相同内容
  • 可选加速:如果需要更高性能,可以把字段填充逻辑用numpy向量化操作实现,进一步提升行处理速度

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 13:36:06