我有一个csv文件,我想删除重复的行,但它太大,无法放入内存.我找到了一种方法来完成它,但我的猜测是,这不是最好的方法.
每行包含15个字段和数百个字符,并且需要所有字段来确定唯一性.我没有比较整行来找到重复,而是hash(row-as-a-string)
在试图节省内存.我设置了一个过滤器,将数据划分为大致相等数量的行(例如,一周中的几天),并且每个分区都足够小,以使该分区的散列值查找表适合内存.我为每个分区传递一次文件,检查唯一的行并将它们写入第二个文件(伪代码):
import csv
headers={'DayOfWeek':None, 'a':None, 'b':None}
outs=csv.DictWriter(open('c:\dedupedFile.csv','wb')
days=['Mon','Tue','Wed','Thu','Fri','Sat','Sun']
outs.writerows(headers)
for day in days:
htable={}
ins=csv.DictReader(open('c:\bigfile.csv','rb'),headers)
for line in ins:
hvalue=hash(reduce(lambda x,y:x+y,line.itervalues()))
if line['DayOfWeek']==day:
if hvalue in htable:
pass
else:
htable[hvalue]=None
outs.writerow(line)
Run Code Online (Sandbox Code Playgroud)
我想加快速度的一种方法是找到一个更好的过滤器来减少必要的通过次数.假设行的长度均匀分布,可能代替
for day in days:
Run Code Online (Sandbox Code Playgroud)
和
if line['DayOfWeek']==day:
Run Code Online (Sandbox Code Playgroud)
我们有
for i in range(n):
Run Code Online (Sandbox Code Playgroud)
和
if len(reduce(lambda x,y:x+y,line.itervalues())%n)==i:
Run Code Online (Sandbox Code Playgroud)
其中'n'和内存一样小.但这仍然使用相同的方法.
Wayne Werner在下面提供了一个很好的实用解决方案; 我很好奇是否有更好/更快/更简单的方法从算法的角度来做这件事.
PS我只限于Python 2.5.