首先,我知道有类似问题的答案,但是......我的问题与速度和内存效率有关。
我有一个60 GB的文本文件,其中包含17个字段和460,368,082条记录。第3列具有个人的ID,同一个人可以在此文件中包含多个记录。让我们调用此文件File A
。
我有第二个文件File B
,其ID为1,000,000个人,我想提取File A
中ID为File B
的行。
我有一台Windows PC,我愿意用C或Python做这件事,或者更快的......但不确定如何快速有效地做到这一点。
到目前为止,根据我的计算,我提出的每个解决方案都需要1。5年。
答案 0 :(得分:1)
您正在寻找的是排序合并连接。我们的想法是对要加入的列(ID)上的文件A进行排序。在要加入的列(ID)上对文件B进行排序。然后使用合并算法读取这两个文件,忽略两个文件中没有匹配的文件。
对文件进行排序可能需要创建中间文件。
如果数据位于带分隔符的文本文件中,您还可以使用linux sort命令行实用程序来执行排序。
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以获得匹配。我认为任何一种语言都可以正常使用,这取决于你对哪种语言更加满意。
答案 1 :(得分:0)
取决于,如果它未被排序,你将不得不搜索整个东西,我将使用多个线程。如果你不得不多次进行这种搜索,我也会创建一个索引。
如果你有大量的内存,你可以创建一个哈希表来保存字符串。然后,您可以将第一个文件中的所有字符串加载到哈希表中。然后,一次一个地加载第二个文件中的每个字符串。对于每个字符串,检查它是否在哈希表中。如果是,请举报比赛。这种方法使用O(m)内存(其中m是第一个文件中的字符串数)并且至少需要Ω(m + n)个时间,甚至可能更多,具体取决于散列函数的工作方式。这也是(几乎可以肯定)解决问题的最简单,最直接的方法。
如果你有很少的ram可以处理大量的磁盘空间:https://en.wikipedia.org/wiki/External_sorting,你可以将其转换为O(n log n)时间。
答案 2 :(得分:0)
听起来你想要做的是先阅读File B
,收集ID。您可以将ID存储在set
或dict
。
然后阅读File A
。对于File A
中的每一行,通过检查File B
或set
中的成员身份,提取ID,然后查看它是否在dict
中。如果没有,则跳过该行并继续下一行。如果是,则根据需要处理该行。