【发布时间】:2017-07-24 09:46:34
【问题描述】:
我们领域的大量光谱数据、模拟输出文件......来自结构化和非结构化数据的混合体。
一个例子是下面的文件,其中三个点是 代表中间的其他线。
...
...
---------------------------------------------------------------------------------------------------
DGA/MPI-2 Parallel Environment: 4 Molcas's processes are running on 1 node(s) x 4 cores each
----------------------------------------------------------------------------------------------------
...
...
Mulliken charges per centre and basis function type
---------------------------------------------------
O1 C2 CR3 O4 CR5 O6 O7 C8 O9 O10 O11 C12
1s 1.9991 1.9984 2.0000 1.9992 2.0000 1.9986 1.9986 1.9983 1.9993 1.9987 1.9986 1.9983
2s 1.7994 1.0697 2.0000 1.8080 2.0000 1.8648 1.8692 1.0827 1.7580 1.8781 1.8582 1.0834
2px 1.9368 0.7559 2.0000 1.9364 2.0000 1.6998 1.6786 0.7228 1.9829 1.6891 1.7016 0.7757
2pz 1.4406 0.6506 2.0000 1.4297 2.0000 1.7096 1.6791 0.6758 1.4469 1.6580 1.7045 0.6490
2py 1.7790 0.5652 2.0000 1.7909 2.0000 1.5122 1.5263 0.5719 1.5781 1.4733 1.5474 0.5655
3s -0.0040 0.0107 1.9934 -0.0041 1.9932 -0.0093 -0.0095 0.0091 -0.0064 -0.0072 -0.0099 0.0106
3px -0.0032 0.0205 1.9939 -0.0031 1.9942 -0.0111 -0.0139 0.0189 -0.0015 -0.0107 -0.0145 0.0460
3pz -0.0122 -0.0118 1.9936 -0.0114 1.9936 -0.0077 -0.0073 -0.0072 -0.0102 -0.0070 -0.0076 -0.0035
3py -0.0021 0.1446 1.9912 0.0005 1.9919 -0.0113 -0.0112 0.1360 -0.0070 -0.0087 -0.0125 0.1386
4s 0.0000 0.0000 0.1958 0.0000 0.1914 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000
3d2+ 0.0000 0.0000 0.6978 0.0000 0.6939 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000
3d1+ 0.0000 0.0000 0.4320 0.0000 0.4423 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000
通常某些部分必须手动解析,但如果您到达示例表的开头,则有关表大小的所有信息都在手边,使用成品表阅读器会很棒。问题是,我认识的所有典型读者都不允许给出字节偏移量。 (csv 模块、pandas、numpy)
这导致两种可能的解决方法:
- 给出了行偏移。这意味着被调用的 csv 阅读器将从头开始读取整个文件并自行计算换行符。我知道它们通常是用 C 语言实现的,而且速度仍然很快,但我认为丢掉可用信息很难看。
- 创建一个字符串并作为
StringIO对象传递给阅读器。
如以下示例代码:
import io
with open('test.log') as f:
title = 'Mulliken charges per centre and basis function type'
for line in f:
if title == line.strip():
break
f.readline()
known_from_previous_parsing = 18
mull_charges = ''.join([f.readline() for j in range(known_from_previous_parsing)])
mull_charges = io.StringIO(mull_charges)
mull_charges = pd.read_csv(mull_charges, delim_whitespace=True)
第二种方法的问题在于,它将表整体写入内存,从而放弃了自动缓冲的所有优点...... (在你问之前,这不是过早的优化,表可能会变得如此之大,以至于整体读取它们会导致交换。)
所以我的问题是:python 中是否有允许指定字节偏移量的 csv 解析工具。或者更笼统地说,我的方法是否走在正确的轨道上,我应该如何处理结构化和非结构化数据的这种混合?
【问题讨论】:
-
您可以将
f与nrows=known_from_previous_parsing一起传递给read_csv,无需先将其读入内存。 -
你的目标是什么,
pandas或csv或?