从文件中提取与另一个文件中的条件匹配的某些行

Extracting certain rows from a file that match a condition from another file

本文关键字:文件 条件 提取 另一个      更新时间:2023-10-16

所以首先,我知道类似的问题有一些答案,但是。。。我的问题与速度和内存效率有关。

我有一个60 GB的文本文件,其中有17个字段和460368082条记录。第3列有个人的ID,同一个人在该文件中可以有多条记录。让我们调用这个文件File A

我有第二个文件File B,它的ID为1000000个人,我想提取File A中ID为File B的行。

我有一台windows PC,我对用C或Python或其他更快的语言来做这件事持开放态度。。。但不确定如何快速有效地完成。

根据我的计算,到目前为止,我提出的每一个解决方案都需要1.5年以上的时间。

您想要的是一个排序合并联接。其想法是对要加入的列(ID)上的文件A进行排序。对要加入的列(ID)上的文件B进行排序。然后使用合并算法读取这两个文件,忽略两者不匹配的文件。

对文件进行排序可能需要创建中间文件。

如果数据在带有分隔符的文本文件中,您也可以使用linux排序命令行实用程序来执行排序。

 sort -k3,3 -t'|' fileA > fileA.sorted
 sort fileB > fileB.sorted
 dos2unix fileB.sorted  #make sure the line endings are same style
 dos2unix fileA.sorted  #make sure the line endings are same style

如果dos2unix不可用,这可能被用作替代

 sort -k3,3 -t'|' fileA | tr -d 'r' > fileA.sorted
 sort fileB | tr -d 'r' > fileB.sorted

加入文件

 join -1 3 -2 1 -t'|' fileA.sorted fileB.sorted

另一种选择是,如果您有足够的RAM,则可以在内存中以HashMap类型的结构加载文件B。然后读取文件A,并在HashMap中查找匹配项。我认为任何一种语言都可以,只是取决于你对哪种语言更熟悉。

这取决于,如果它没有排序,你将不得不搜索整个东西,我会使用多个线程。如果你要多次搜索,我也会创建一个索引。

如果你有大量的内存,你可以创建一个哈希表来保存字符串。然后,您可以将第一个文件中的所有字符串加载到哈希表中。然后,从第二个文件中一次加载一个字符串。对于每个字符串,请检查它是否在哈希表中。如果是,请报告匹配。这种方法使用O(m)内存(其中m是第一个文件中的字符串数),并且至少需要Ω(m+n)时间,甚至可能更多,这取决于哈希函数的工作方式。这也是(几乎可以肯定的)解决问题最简单、最直接的方法。

如果您的ram很少,但有大量的磁盘空间:https://en.wikipedia.org/wiki/External_sorting,您可以获得O(n log n)时间。

听起来您想要做的是首先读取File B,收集ID。您可以将ID存储在setdict中。

然后读取File A。对于File A中的每一行,提取ID,然后通过检查setdict中的成员身份来查看它是否在File B中。如果没有,则跳过该行,继续下一行。如果是,则根据需要处理该行。