我有一个很大的文本文件要解析。 主要模式如下:
step 1
[n1 lines of headers]
3 3 2
0.25 0.43 12.62 1.22 8.97
12.89 89.72 34.87 55.45 17.62
4.25 16.78 98.01 1.16 32.26
0.90 0.78 11.87
step 2
[n2 != n1 lines of headers]
3 3 2
0.25 0.43 12.62 1.22 8.97
12.89 89.72 34.87 55.45 17.62
4.25 16.78 98.01 1.16 32.26
0.90 0.78 11.87
step 3
[(n3 != n1) and (n3 !=n2) lines of headers]
3 3 2
0.25 0.43 12.62 1.22 8.97
12.89 89.72 34.87 55.45 17.62
4.25 16.78 98.01 1.16 32.26
0.90 0.78 11.87
换句话说,:
分隔符:步骤#
已知长度的标题(行号,而不是字节)
数据三维形状:nz,ny,nx
数据:fortran格式化,原始数据集中的~10个浮点数/行
我只是想提取数据,将它们转换为浮点数,将它放在一个numpy数组中,然后将ndarray.reshape转换为给定的形状。
我已经做了一些编程......主要的想法是
我想首先避免使用正则表达式,因为这会使事情变得很慢。完成第一步已经需要3-4分钟(浏览文件以获得每个部分的偏移量)。
问题在于我基本上使用file.tell()
方法来获取分隔符位置:
[file.tell() - len(sep) for line in file if sep in line]
问题是双重的:
file.tell()
给出正确的分隔符位置,对于较长的文件,它不会。我怀疑file.tell()
不应该在循环中使用,既不使用显式file.readline()
也不使用隐式for line in file
(我试过两者)。我不知道,但结果是:对于大文件,[file.tell() for line in file if sep in line]
不系统地在分隔符后面提供行的位置。sep
是一个字符串(字节),包含文件的第一行(第一个分隔符)。有谁知道我应该如何解析它?
注意:我首先找到偏移量,因为我希望能够浏览文件内部:我可能只想要第10个数据集或第500个数据集......
sep = "step "
with open("myfile") as f_in:
offsets = [fin.tell() for line in fin if sep in line]
正如我所说,这是在一个简单的例子中,但不是在大文件上。
新测试:
sep = "step "
offsets = []
with open("myfile") as f_in:
for line in f_in:
if sep in line:
print line
offsets.append(f_in.tell())
打印的行对应于分隔符,毫无疑问。但是使用f_in.tell()
获得的偏移量与下一行不对应。我想文件是在内存中缓冲的,当我尝试在隐式循环中使用f_in.tell()
时,我没有获得当前位置而是缓冲区的结尾。这只是一个疯狂的猜测。
答案 0 :(得分:0)
我得到了答案:for
- 文件上的循环和tell()
相处得不好。就像混合for i in file
和file.readline()
会引发错误一样。
因此,file.tell()
仅使用file.readline()
或file.read()
。
永远不要使用:
for line in file:
[do stuff]
offset = file.tell()
这真是一种耻辱,但就是这样。