我经常处理包含少量列(通常少于10个)和多达数千万行的ascii表。他们看起来像Python熊猫:读文件跳过评论
176.792 -2.30523 0.430772 32016 1 1 2
177.042 -1.87729 0.430562 32016 1 1 1
177.047 -1.54957 0.431853 31136 1 1 1
...
177.403 -0.657246 0.432905 31152 1 1 1
我有大量的Python代码,读取,操纵和保存文件。我一直使用numpy.loadtxt
和numpy.savetxt
来做到这一点。但是numpy.loadtxt
需要至少5-6Gb的RAM来读取1Gb ASCII文件。
昨天我发现了熊猫,它解决了我几乎所有的问题:pandas.read_table
和numpy.savetxt
一起提高了我的脚本的执行速度(2)3或4,同时非常有效地提高内存。
一切都很好,直到我尝试读入包含一些注释行开头的文件时。文档字符串(v = 0.10.1.dev_f73128e)告诉我,行注释不受支持,并且可能会发生。我认为这会很好:我非常喜欢排除numpy.loadtxt
中的评论。 有没有关于如何可用的想法?也很高兴有可能跳过这些行(该文件指出,他们将作为empy返回)
不知道我的文件中有多少注释行(我处理数以千计的注释行来自不同的人) ,因为现在我打开该文件,计算行开始在文件开头评论数:
def n_comments(fn, comment):
with open(fname, 'r') as f:
n_lines = 0
pattern = re.compile("^\s*{0}".format(comment))
for l in f:
if pattern.search(l) is None:
break
else:
n_lines += 1
return n_lines
然后
pandas.read_table(fname, skiprows=n_comments(fname, '#'), header=None, sep='\s')
有没有什么更好的方法(也许内大熊猫)去做吧?
最后,在发布之前,我看了一下pandas.io.parsers.py
的代码,了解pandas.read_table
如何工作,但我迷路了。任何人都可以指向我实现阅读文件的地方吗?
感谢
EDIT2:我想获得一些改善摆脱一些@ThorstenKranz第二实施FileWrapper
的if
的,但没有得到几乎没有改善
class FileWrapper(file):
def __init__(self, comment_literal, *args):
super(FileWrapper, self).__init__(*args)
self._comment_literal = comment_literal
self._next = self._next_comment
def next(self):
return self._next()
def _next_comment(self):
while True:
line = super(FileWrapper, self).next()
if not line.strip()[0] == self._comment_literal:
self._next = self._next_no_comment
return line
def _next_no_comment(self):
return super(FileWrapper, self).next()
对于记录:编辑以包含从文件起始处开始对已注释行数进行计数的功能 –