阅读巨大的 .csv 文件。
阅读巨大的 .csv 文件。
我目前正在尝试在Python 2.7中读取带有多达1百万行和200列的csv文件(文件范围从100mb到1.6gb)。对于行数不超过300,000的文件,我可以做到这一点(但速度非常慢),但一旦超过这个数字,我就会遇到内存错误。我的代码如下:
def getdata(filename, criteria): data=[] for criterion in criteria: data.append(getstuff(filename, criteron)) return data def getstuff(filename, criterion): import csv data=[] with open(filename, "rb") as csvfile: datareader=csv.reader(csvfile) for row in datareader: if row[3]=="column header": data.append(row) elif len(data)<2 and row[3]!=criterion: pass elif row[3]==criterion: data.append(row) else: return data
getstuff函数中的else子句的原因是,满足标准的所有元素将在csv文件中一起列出,因此当我超过它们时,我会离开循环以节省时间。
我的问题是:
- 如何使它能够处理更大的文件?
- 有什么方法可以使它更快?
我的计算机具有8GB RAM,运行64位Windows 7,处理器为3.40 GHz(我不确定您需要什么信息)。
admin 更改状态以发布 2023年5月21日
你正在将所有行读入列表中,然后处理该列表。 不要这样做。
在生成行时处理它们。如果需要先过滤数据,请使用生成器函数:
import csv def getstuff(filename, criterion): with open(filename, "rb") as csvfile: datareader = csv.reader(csvfile) yield next(datareader) # yield the header row count = 0 for row in datareader: if row[3] == criterion: yield row count += 1 elif count: # done when having read a consecutive series of rows return
我还简化了您的过滤测试;逻辑相同但更简明。
因为您只匹配符合条件的单个行序列,所以还可以使用:
import csv from itertools import dropwhile, takewhile def getstuff(filename, criterion): with open(filename, "rb") as csvfile: datareader = csv.reader(csvfile) yield next(datareader) # yield the header row # first row, plus any subsequent rows that match, then stop # reading altogether # Python 2: use `for row in takewhile(...): yield row` instead # instead of `yield from takewhile(...)`. yield from takewhile( lambda r: r[3] == criterion, dropwhile(lambda r: r[3] != criterion, datareader)) return
现在可以直接循环遍历 getstuff()
。 在 getdata()
中也是同样的处理:
def getdata(filename, criteria): for criterion in criteria: for row in getstuff(filename, criterion): yield row
现在可以直接循环遍历您的代码中的 getdata()
:
for row in getdata(somefilename, sequence_of_criteria): # process row
现在您只保留一行内存,而不是每个条件千行重复。
yield
使函数成为生成器函数,这意味着在您开始循环遍历之前它不会执行任何操作。