Python读取一个大文件并消除重复行
我有一个巨大的文本文件,其中有重复的行。规模约为15000000行。我想找到最有效的方法来读入这些行并消除重复。我正在考虑的一些方法如下:-Python读取一个大文件并消除重复行,python,large-files,Python,Large Files,我有一个巨大的文本文件,其中有重复的行。规模约为15000000行。我想找到最有效的方法来读入这些行并消除重复。我正在考虑的一些方法如下:- 读入整个文件,做一个列表(设置(行)) 一次读入10k行,列出(设置(行)),在列表中再读入10k行,列出(设置(行))。重复一遍 你将如何处理这个问题?任何形式的多处理都会有帮助吗?多处理不会真正有帮助,因为内存是瓶颈。您将需要使用哈希: 读线 计算散列,例如md5,在一组遇到的所有散列中查找它 如果在集合中未找到哈希,则输出行,并将此哈希添加到集合中
你将如何处理这个问题?任何形式的多处理都会有帮助吗?多处理不会真正有帮助,因为内存是瓶颈。您将需要使用哈希:
- md5占用128位,因此即使没有开销,它的ram也超过2G
- set和dict的内存开销很大
另外,如果您不关心结果文件中的行顺序,您可以根据一些散列函数(md5以a开头的行,md5以b开头的行等)将文件拆分为较小的文件。这将使它们足够小,只需对它们进行
排序| uniq
即可(如果愿意,也可以使用python在内存中进行排序)并连接结果。这里的内存是问题所在,因此可能无法将整个文件加载到内存中
由于不需要维护行的顺序,一个可能的选择是执行某种基数排序:
for each line in file:
put this line into a new file based on the first character
新文件现在应该小一些,如果某些文件仍然太大(例如,原始文件中的每一行都以a
开头),您可以根据第2、第3等字符递归分割文件
一旦这些文件足够小,可以放入内存,您就可以执行列表(set(list))
方法,然后在完成后将文件重新组合在一起。或者,如果您可以使用uniq
UNIX命令行工具,也可以使用它
请注意,基数排序部分可以很容易地并行化,因为每一行都独立于其他行。请考虑是否真的需要在python中解决这个问题。你可以
- 调出
和sort
,这是大多数posix系统上的标准工具。他们将完成这项工作,速度更快,并在您考虑之前解决边缘问题(如内存不足)uniq
- 最简单的解决方案可能是使用
-包创建一个内存中的数据库,将所有行插入一个临时表,并从中执行sqlite
。同样,sqlite的性能比纯python要好选择distinct…
set()
在比较字符串成本O(mn)
时不会起任何作用,而且当你使用大约15000000
行时,我想这种方法似乎不可行。@tommy.carstensen文件没有排序。每行的字符数各不相同~每行13-20个字符。重复行的百分比有多大?超过50%?低于1%?如果有很大一部分行是重复的,我会分而治之。这些行平均有13-20个字符,所以我想不需要计算md5(128位)?不需要,或者可以使用更短的散列,例如python的hash()函数并节省内存。我不确定它有多好。@tommy.carstensen我想有,因为总行数是15000000
,在如此大的数据集上匹配字符串会花费很多时间,我想这种哈希方法比set()
好。我喜欢这种哈希方法。问题是如何处理哈希冲突。可以有两个不同的字符串,但其哈希相同。我不知道默认的散列函数有多好,所以按照@letitbee的建议使用md5可能更好。我认为可以截断sha1,仍然可以得到很好的熵。但由于输入集如此之大,我不知道这是一个多么好的主意。不,sqlite会让它变得更糟,而不是更好。实际上,您可以使用一个常规的、基于磁盘的数据库来实现这一点,但它的效率非常低,而且这并不能解决问题,而是让其他人来解决它。