我们领域的许多光谱数据,模拟输出文件......都是结构化和非结构化数据的混合。
一个例子是以下文件,其中三个点是 站在中间的其他线路上。
...
...
---------------------------------------------------------------------------------------------------
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模块,熊猫,numpy)
这导致两种可能的解决方法:
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解析工具允许指定字节偏移量。或者问一般情况,我的方法是否正确,我应该如何解决这种结构化和非结构化数据的混合?
答案 0 :(得分:1)
不能告诉熊猫,但使用csv
模块,您可以推进文件指针(使用readline()
或next()
),直到您在...之前表格数据的第一行,然后像任何普通的csv文件一样继续(假设您在表格数据之后没有更多的非结构化文本):
offset.dat
This is useles
This is useles
This is useles
Data:
AAA,42
BBB,56
CCC,8878
Python shell:
>>> import csv
>>> f = open("offset.dat")
>>> line = f.next()
>>> while not line.startswith("Data:"):
... line = f.next()
...
>>> line
'Data:\n'
>>> r = csv.reader(f)
>>> r.next()
['AAA', '42']
>>> r.next()
['BBB', '56']
>>> r.next()
['CCC', '8878']
答案 1 :(得分:1)
Pandas足够聪明地处理这个问题,假设这个内容位于文件的末尾。使用skiprows
参数。
>>> import pandas as pd
>>> df = pd.read_csv('temp.txt', sep='\s+',skiprows=10)
>>> df
O1 C2 CR3 O4 CR5 O6 O7 C8 O9 \
1s 1.9991 1.9984 2.0000 1.9992 2.0000 1.9986 1.9986 1.9983 1.9993
2s 1.7994 1.0697 2.0000 1.8080 2.0000 1.8648 1.8692 1.0827 1.7580
2px 1.9368 0.7559 2.0000 1.9364 2.0000 1.6998 1.6786 0.7228 1.9829
2pz 1.4406 0.6506 2.0000 1.4297 2.0000 1.7096 1.6791 0.6758 1.4469
2py 1.7790 0.5652 2.0000 1.7909 2.0000 1.5122 1.5263 0.5719 1.5781
3s -0.0040 0.0107 1.9934 -0.0041 1.9932 -0.0093 -0.0095 0.0091 -0.0064
3px -0.0032 0.0205 1.9939 -0.0031 1.9942 -0.0111 -0.0139 0.0189 -0.0015
3pz -0.0122 -0.0118 1.9936 -0.0114 1.9936 -0.0077 -0.0073 -0.0072 -0.0102
3py -0.0021 0.1446 1.9912 0.0005 1.9919 -0.0113 -0.0112 0.1360 -0.0070
4s 0.0000 0.0000 0.1958 0.0000 0.1914 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
3d1+ 0.0000 0.0000 0.4320 0.0000 0.4423 0.0000 0.0000 0.0000 0.0000
O10 O11 C12
1s 1.9987 1.9986 1.9983
2s 1.8781 1.8582 1.0834
2px 1.6891 1.7016 0.7757
2pz 1.6580 1.7045 0.6490
2py 1.4733 1.5474 0.5655
3s -0.0072 -0.0099 0.0106
3px -0.0107 -0.0145 0.0460
3pz -0.0070 -0.0076 -0.0035
3py -0.0087 -0.0125 0.1386
4s 0.0000 0.0000 0.0000
3d2+ 0.0000 0.0000 0.0000
3d1+ 0.0000 0.0000 0.0000
如果它不是,并且您知道或可以计算表格中的行数,那么您仍然可以将此类脚本与rows
参数一起使用。
一旦你用pandas读取了这个表,就可以将它发送到csv,sql db,excel等。