1

所以我试图在python中读取一个大数据文件。如果数据有一列和一百万行,我会这样做:

fp = open(ifile,'r');

for row in fp:  
    process row

当我正在读取的数据有 100 万列而只有 1 行时,我的问题就出现了。我想要的是与fscanf()C 中的函数类似的功能。

即,

while not EOF:  
    part_row = read_next(%lf)  
    work on part_row

fp.read(%lf)如果我知道格式是long float什么,我可以使用。

有什么想法吗?

4

3 回答 3

3

一百万个文本格式的浮点数真的不是那么大......所以除非它证明了某种瓶颈,否则我不会担心它,只是这样做:

with open('file') as fin:
    my_data = [process_line(word) for word in fin.read().split()]

一个可能的替代方案(假设空格分隔的“单词”)是这样的:

import mmap, re

with open('whatever.txt') as fin:
    mf = mmap.mmap(fin.fileno(), 0, access=mmap.ACCESS_READ)
    for word in re.finditer(r'(.*?)\s', mf):
        print word.group(1)

这将扫描整个文件并有效地提供大量的字流,无论行/列如何。

于 2013-02-21T00:06:21.023 回答
1

有两种基本方法可以解决这个问题:

首先,您可以编写一个read_column带有自己显式缓冲区的函数,或者作为生成器函数:

def column_reader(fp):
    buf = ''
    while True:
        col_and_buf = self.buf.split(',', 1)
        while len(col_and_buf) == 1:
            buf += fp.read(4096)
            col_and_buf = buf.split(',', 1)
        col, buf = col_and_buf
        yield col

……或作为一个班级:

class ColumnReader(object):
    def __init__(self, fp):
        self.fp, self.buf = fp, ''
    def next(self):
        col_and_buf = self.buf.split(',', 1)
        while len(col_and_buf) == 1:
            self.buf += self.fp.read(4096)
            col_and_buf = self.buf.split(',', 1)
        self.buf = buf
        return col

但是,如果您编写一个read_until在内部处理缓冲的函数,那么您可以这样做:

next_col = read_until(fp, ',')[:-1]

ActiveState 上有多个read_until配方。

或者,如果你mmap是文件,你实际上是免费获得的。您可以将文件视为一个巨大的字符串并在其上使用find(或正则表达式)。(这假设整个文件都适合您的虚拟地址空间——在 64 位 Python 构建中可能不是问题,但在 32 位构建中可能是。)


显然这些都是不完整的。他们不处理 EOF 或换行符(在现实生活中,您可能有行一百万列,而不是一列,对吧?)等。但这应该足以说明这个想法。

于 2013-02-21T00:14:23.210 回答
0

您可以使用yield.

def read_in_chunks(file_object, chunk_size=1024):
    while True:
        data = file_object.read(chunk_size)
        if not data:
            break
        yield data


f = open('your_file.txt')
for piece in read_in_chunks(f):
    process_data(piece)

查看这个问题以获取更多示例。

于 2013-02-21T00:08:16.243 回答