使用python过滤大文件,使用另一个的内容

时间:2012-06-21 05:22:17

标签: python optimization filter compare

我有一个~1GB的数据条目文本文件和另一个我想用来过滤它们的名字列表。遍历每个条目的每个名称将非常慢。在python中执行此操作的最有效方法是什么?如果名称嵌入在条目中,是否可以使用哈希表?我可以使用名称部分始终放置的事实吗?

示例文件:

条目文件 - 条目的每个部分由制表符分隔,直到名称

246   lalala   name="Jack";surname="Smith"
1357   dedada   name="Mary";surname="White"
123456  lala   name="Dan";surname="Brown"
555555   lalala   name="Jack";surname="Joe"

命名文件 - 每个都在换行符

Jack
Dan
Ryan

所需输出 - 仅在名称文件中具有名称的条目

246   lalala   name="Jack";surname="Smith"
123456  lala   name="Dan";surname="Brown"
555555   lalala   name="Jack";surname="Joe"

4 个答案:

答案 0 :(得分:6)

您可以使用set数据结构来存储名称 - 它提供了有效的查找,但如果名称列表非常大,那么您可能会遇到内存问题。

一般的想法是遍历所有名称,将它们添加到set,然后检查数据文件中每行的每个名称是否包含在set中。由于条目的格式不变,您应该能够使用简单的正则表达式提取名称。

如果您遇到名称set大小的问题,您可以从名称文件中读取 n 行,并为每组名称重复此过程,除非您需要排序

答案 1 :(得分:2)

我的第一直觉是创建一个名字作为键的字典,假设使用字典中的键哈希来查找名称是最有效的。

根据@rfw的答案,使用set名称,我编辑了如下代码,并使用dict名称和{{1}对两种方法进行了测试}。

我构建了一个超过40 M记录和超过5400个名称的虚拟数据集。使用此数据集,set方法始终在我的机器上具有优势。

set

我假设一个import re from collections import Counter import time # names file downloaded from http://www.tucows.com/preview/520007 # the set contains over 5400 names f = open('./names.txt', 'r') names = [ name.rstrip() for name in f.read().split(',') ] name_set = set(names) # set of unique names names_dict = Counter(names) # Counter ~= dict of names with counts # Expect: 246 lalala name="Jack";surname="Smith" pattern = re.compile(r'.*\sname="([^"]*)"') def select_rows_set(): f = open('./data.txt', 'r') out_f = open('./data_out_set.txt', 'a') for record in f.readlines(): name = pattern.match(record).groups()[0] if name in name_set: out_f.write(record) out_f.close() f.close() def select_rows_dict(): f = open('./data.txt', 'r') out_f = open('./data_out_dict.txt', 'a') for record in f.readlines(): name = pattern.match(record).groups()[0] if name in names_dict: out_f.write(record) out_f.close() f.close() if __name__ == '__main__': # One round to time the use of name_set t0 = time.time() select_rows_set() t1 = time.time() time_for_set = t1-t0 print 'Total set: ', time_for_set # One round to time the use of names_dict t0 = time.time() select_rows_dict() t1 = time.time() time_for_dict = t1-t0 print 'Total dict: ', time_for_dict ,一个字典,并且更容易从数据集构建,不会增加访问时间的任何开销。如果我错过了什么,很高兴得到纠正。

答案 2 :(得分:1)

您的数据显然是一个表格,因此可能适用。 Data structure for maintaining tabular data in memory?

答案 3 :(得分:1)

您可以使用自己的“按名称搜索”功能创建自定义数据结构。这是某种词典列表。这应该比文本文件的大小占用更少的内存,因为它将删除每行上的重复信息,例如“name”和“surname”,这将是字典键。如果您知道一点SQL(这里需要的很少),那么请使用Filter large file using python, using contents of another