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

如何用Pandas处理原子模拟软件生成的不规则CSV文件

问题描述

我有一个老旧原子模拟软件生成的格式混乱的CSV文件,需要导入为Pandas DataFrame。文件格式示例如下:

ITEM: TIMESTEP
0
ITEM: NUMBER OF ATOMS
491
ITEM: BOX BOUNDS pp pp pp
0.0000000000000000e+00 2.8000000000000000e+01
0.0000000000000000e+00 2.8000000000000000e+01
0.0000000000000000e+00 2.8000000000000000e+01
ITEM: ATOMS id type xs ys zs
1 1 0 0 0.142857
2 1 0.0714286 0.0714286 0.142857
3 1 0.0714286 0 0.214286
4 1 0 0.0714286 0.214286
...
491 1 2 2.3 0.4
ITEM: TIMESTEP
0
ITEM: NUMBER OF ATOMS
491
ITEM: BOX BOUNDS pp pp pp
0.0000000000000000e+00 2.8000000000000000e+01
0.0000000000000000e+00 2.8000000000000000e+01
0.0000000000000000e+00 2.8000000000000000e+01
ITEM: ATOMS id type xs ys zs
1 1 0 0 0.142857
2 1 0.0714286 0.0714286 0.142857
3 1 0.0714286 0 0.214286
4 1 0 0.0714286 0.214286
...
491 215 0.4 12.4 2.4
...
...
ITEM: TIMESTEP
1002
...

文件包含重复的头部信息(含迭代次数TIMESTEP),我希望将其转换为包含['id', 'type', 'xs', 'ys', 'zs']字段及新增TIMESTEP列的二维DataFrame,也可采用TIMESTEP为外层索引的多层索引结构,且可丢弃头部的信息行(1-9行)。理想转换结果示例如下:

Index   id  type        xs          ys          zs          TIMESTEP
    1       1   1           0           0           0.142857    0
    2       1   1           0.0714286   0.0714286   0.142857    0
    3       1   1           0.0714286   0           0.214286    0
    4       1   1           0           0.0714286   0.214286    0
    5       1   1           0.142857    0           0.142857    0
    ...
    474     1   1           0.78636     0.788005    0.425791    100002

请问是建议编写字符串格式化脚本(附示例更佳),还是通过Pandas read_csv的参数配置直接实现该转换?

解决方案

直接用read_csv的参数很难完美处理这种重复的非标准头部结构,更建议编写脚本逐行解析,逻辑清晰且容易适配后续格式变化。以下是实现示例:

import pandas as pd

def parse_lammps_dump(file_path):
    data = []
    current_timestep = None
    with open(file_path, 'r') as f:
        while True:
            line = f.readline()
            if not line:
                break
            # 捕获TIMESTEP值
            if line.startswith('ITEM: TIMESTEP'):
                current_timestep = int(f.readline().strip())
            # 捕获原子数据段
            elif line.startswith('ITEM: ATOMS'):
                # 获取列名
                cols = line.strip().split()[2:]
                # 读取所有原子行,直到下一个ITEM开头的行
                while True:
                    atom_line = f.readline()
                    if not atom_line or atom_line.startswith('ITEM:'):
                        # 把ITEM行放回去,供下一轮循环处理
                        f.seek(f.tell() - len(atom_line))
                        break
                    atom_vals = atom_line.strip().split()
                    # 转换为数值类型,添加timestep列
                    row = dict(zip(cols, map(float, atom_vals)))
                    row['TIMESTEP'] = current_timestep
                    data.append(row)
    # 转换为DataFrame
    df = pd.DataFrame(data)
    # 可选:设置多层索引
    # df = df.set_index(['TIMESTEP', 'id'])
    return df

# 使用示例
df = parse_lammps_dump('your_dump_file.txt')
print(df.head())

脚本优势

  • 精准处理重复的头部块,不会遗漏任何TIMESTEP对应的原子数据
  • 灵活控制数据类型转换,避免read_csv自动解析可能出现的错误
  • 可以轻松扩展处理其他头部信息(如BOX BOUNDS),如果后续需要用到的话

如果非要尝试read_csv,可以结合skiprows和chunksize,但需要提前知道每个TIMESTEP块的行数,维护成本高,一旦原子数变化就会出错,远不如脚本可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 05:25:24