所以我试图在python中读取一个大型数据文件。如果数据有一列和100万行,我会这样做:
fp = open(ifile,'r');
for row in fp:
process row
当我正在阅读的数据有100万列而且只有1行时,我的问题就出现了。我想要的是与C中的fscanf()
函数类似的功能。
即,
while not EOF:
part_row = read_next(%lf)
work on part_row
如果我知道格式是fp.read(%lf)
或其他什么,我可以使用long float
。
有什么想法吗?
答案 0 :(得分: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)
这将扫描整个文件并有效地提供大量的字流,无论行/列如何。
答案 1 :(得分: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或换行(在现实生活中你可能有六行行,而不是一行,对吗?)等等。但这应该足以表明这个想法。< / p>
答案 2 :(得分: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)
请查看this question了解更多示例。