我有30个非常大的文本文件,其中包含两列(domain | ip),其中包含大量重复的记录。我最终想要的是每个ip的唯一域名。这就是文件的样子:
man.bia.com|23.45.33.3
to.biaa.co.uk|23.45.33.3
man.bia.com|23.45.33.3
yahoo.com|34.55.44.2
yahoo.com|56.55.37.67
我已经尝试过像sqlite之前建议的解决方案,但这不合适因为每个文件需要花费很多时间来解析。 How to parse files larger than 100GB in Python?
是否有人建议在有限的时间内使用有限的内存解析如此庞大的数据集?
答案 0 :(得分:0)
如果你这样做
sort -t'|' -k2 -k1,1 files
后跟这个python代码
current_ip = 0
domain_tracking = []
with open(output, 'w') as fout:
for filename in files:
with open(filename, 'rb') as f:
reader = csv.reader(f, delimiter='|')
for domain, ip in reader:
domain_tracking.append(domain)
if ip == current_ip:
pass
else:
fout.write(ip + '|' + ','.join(set(domain_tracking))))
current_ip = ip
domain_tracking = []
这只是通过你的有序文件并且每次只编写一次ip后跟一个域,以防只有一个或多个域,以防重复,内存中的占用空间很小。
答案 1 :(得分:0)
排序对于大文件可能需要很长时间,我会尝试使用dict
和set
的纯Python解决方案:
import collections
import fileinput
results = collections.defaultdict(set)
for line in fileinput.input():
try:
domain, ip = line.strip().split('|')
except ValueError:
continue
results[ip].add(domain)
print results # or write to file or anything
这有复杂性O(n),只有IO才会成为瓶颈。 除非你真的碰壁,否则不要担心内存 - 这就是交换分区的用途,对吗?
如果您的结果集非常大(主要是唯一对),并且交换需要很长时间,您可以在较小批次上运行此脚本,将部分结果(更好地适合内存)写入文件桶(每个IP范围)分开文件)。然后,您可以使用另一个脚本分别解析每个存储桶。