首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何以内存高效的方式拆分和解析python中的大文本文件?

如何以内存高效的方式拆分和解析python中的大文本文件?
EN

Stack Overflow用户
提问于 2013-03-24 19:19:53
回答 1查看 1.3K关注 0票数 1

我有一个很大的文本文件要解析。主要模式如下:

代码语言:javascript
复制
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为给定的形状。

我已经做了一些编程..。主要思想是

  1. 首先获取每个分隔符的偏移量(“步骤X")
  2. 跳过nX (n1,n2.)行+1到达数据
  3. 从那里读取字节直到下一个分隔符。

一开始我想避免regex,因为这样会使事情慢很多。只需3-4分钟就能完成第一步(浏览文件以获得每个部分的偏移量)。

问题是,我基本上使用file.tell()方法来获得分隔符的位置:

代码语言:javascript
复制
[file.tell() - len(sep) for line in file if sep in line]

问题有两方面:

  1. 对于较小的文件,file.tell()会给出正确的分隔位置,而对于较长的文件,则不会。我怀疑file.tell()不应该在循环中使用,也不应该使用显式file.readline(),也不应该使用隐式for line in file (我尝试了这两种方法)。我不知道,但结果是:对于大文件,[file.tell() for line in file if sep in line] not会系统地在分隔符之后给出行的位置。
  2. len(sep)不会给出正确的偏移校正,使之回到“分隔符”线的开头。sep是一个字符串(字节),包含文件的第一行(第一个分隔符)。

有人知道我该怎么解析吗?

注:我首先找到了偏移量,因为我想在文件中浏览:我可能只想要第10次数据集或第500次数据集.

1-寻找补偿

代码语言:javascript
复制
sep = "step "
with open("myfile") as f_in:
    offsets = [fin.tell() for line in fin if sep in line]

正如我所说的,这是在简单的例子中起作用的,而不是在大文件上。

新测试:

代码语言:javascript
复制
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()时,我不会得到当前的位置,而是缓冲区的末尾。这只是一个疯狂的猜测。

EN

回答 1

Stack Overflow用户

发布于 2013-03-25 14:59:08

我得到了答案:文件上的for-loops和tell()相处得不太好。就像混合for i in filefile.readline()一样,会产生一个错误。

所以,只使用file.tell()file.readline()file.read()

从未使用过

代码语言:javascript
复制
for line in file:
    [do stuff]
    offset = file.tell()

这真是令人遗憾,但事情就是这样的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15602848

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档