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

读取多个.dat文件最后一行并转换为CSV的技术求助

问题解决与代码修复

现有代码的核心问题

  • 二进制读取导致格式混乱:用'rb'模式打开文件得到bytes对象,直接写入CSV会把每个字节拆成单独元素,引发数据乱码、单元格合并问题。
  • 数据未正确拆分与补全:读取的最后一行未按空格分割列,也没添加自定义行名作为首列。
  • 初始化CSV冗余:空DataFrame导出会生成多余索引列,导致后续追加数据格式混乱。
  • 循环逻辑冗余:while循环完全可替换为if,无需多余嵌套。

修复后的代码方案(两种可选)

方案1:用csv模块直接写入(轻量高效)

from csv import writer
import os.path

allV = ['V0.8','V1','V1.1']
allD = ['D1','D2','D3']
allPhi = ['Phi1','Phi2','Phi3']
allZ = ['Z1','Z2','Z3']
allT = ['T1','T2','T3']

# 初始化CSV并写入表头(可根据实际需求修改列名)
with open('All_Forces.csv', 'w', newline='') as f:
    writer_obj = writer(f)
    headers = ['RowName'] + [f'Col{i+1}' for i in range(25)]
    writer_obj.writerow(headers)

# 遍历所有文件组合
for V in allV:
    for D in allD:
        for Phi in allPhi:
            for Z in allZ:
                for T in allT:
                    datname = f"D:/{V}/{D}/{Phi}/{V}-{T}-{D}-{Phi}-{Z}/ForceDat/body_0_forces.dat"
                    rowname = f"{V}_{T}_{D}_{Phi}_{Z}"
                    
                    if not os.path.isfile(datname):
                        continue  # 文件不存在直接跳过
                    
                    # 高效读取最后一行(避免加载整个大文件)
                    with open(datname, 'rb') as f:
                        f.seek(-2, os.SEEK_END)
                        while f.read(1) != b'\n':
                            f.seek(-2, os.SEEK_CUR)
                        last_line = f.readline().decode('utf-8').strip()
                    
                    # 按空格分割数据,过滤连续空格产生的空字符串
                    data_cols = [col for col in last_line.split(' ') if col]
                    # 拼接行名与数据列
                    row_data = [rowname] + data_cols
                    
                    # 追加写入CSV
                    with open('All_Forces.csv', 'a', newline='') as f:
                        writer_obj = writer(f)
                        writer_obj.writerow(row_data)

方案2:用Pandas(结构化数据处理更便捷)

import pandas as pd
import os.path

allV = ['V0.8','V1','V1.1']
allD = ['D1','D2','D3']
allPhi = ['Phi1','Phi2','Phi3']
allZ = ['Z1','Z2','Z3']
allT = ['T1','T2','T3']

data_list = []

for V in allV:
    for D in allD:
        for Phi in allPhi:
            for Z in allZ:
                for T in allT:
                    datname = f"D:/{V}/{D}/{Phi}/{V}-{T}-{D}-{Phi}-{Z}/ForceDat/body_0_forces.dat"
                    rowname = f"{V}_{T}_{D}_{Phi}_{Z}"
                    
                    if not os.path.isfile(datname):
                        continue
                    
                    # 获取文件总行数,读取最后一行
                    with open(datname, 'r') as f:
                        total_lines = sum(1 for _ in f)
                    df_line = pd.read_csv(datname, sep='\s+', skiprows=total_lines-1, header=None)
                    # 插入自定义行名列
                    df_line.insert(0, 'RowName', rowname)
                    data_list.append(df_line)

# 合并数据并导出CSV
final_df = pd.concat(data_list, ignore_index=True)
final_df.columns = ['RowName'] + [f'Col{i+1}' for i in range(25)]
final_df.to_csv('All_Forces.csv', index=False)

关键修复说明

  • 高效读取最后一行:通过文件指针定位到末尾换行符,避免加载整个大文件,适配10000+行的数据集。
  • 数据分割优化:过滤分割后产生的空字符串,解决原文件连续空格导致的列数错误。
  • CSV格式规范:用newline=''避免Windows系统下出现多余空行,保证列分隔正确。
  • 首列自定义:将生成的rowname作为每行第一个元素,确保CSV首列符合需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 14:53:18