删除大文本文件中的所有重复项

2024-03-09

我真的被这个问题难住了,因此我已经停止工作一段时间了。我处理的数据量非常大。我每周都会收到大约 200GB 的 .txt 数据。数据范围最多可达 5 亿行。其中很多都是重复的。我猜只有 20GB 是独一无二的。我制作了几个自定义程序,包括哈希删除重复项、外部删除重复项,但似乎都不起作用。最新的一个是使用临时数据库,但需要几天时间才能删除数据。

所有程序的问题是它们在某个点后崩溃,并且在这些程序上花费了大量资金之后,我想我应该上网看看是否有人可以提供帮助。我知道这个问题之前已经在这里得到了回答,我花了过去 3 个小时阅读了这里大约 50 个线程,但似乎没有一个线程与我有同样的问题,即巨大的数据集。

有人能给我推荐什么吗?它需要超级准确和快速。最好不要基于内存,因为我只有 32GB 的内存可供使用。


删除重复项的标准方法是对文件进行排序,然后执行顺序传递来删除重复项。对 5 亿行进行排序并不是一件小事,但它确实是可行的。几年前,我每天都有一个进程在 16 GB 的机器上对 50 到 100 GB 的数据进行排序。

顺便说一句,您也许可以使用现成的程序来完成此操作。当然,GNU 排序实用程序可以对大于内存的文件进行排序。我从未在 500 GB 文件上尝试过,但您可以尝试一下。您可以将其与其余部分一起下载GNU 核心实用程序 http://gnuwin32.sourceforge.net/packages/coreutils.htm。该实用程序有一个--unique选项,所以你应该能够sort --unique input-file > output-file。它使用了一种类似于我下面描述的技术。我建议首先在 100 MB 的文件上尝试,然后慢慢处理更大的文件。

使用 GNU 排序和我在下面描述的技术,如果输入目录和临时目录位于不同的物理磁盘上,它的性能会好得多。将输出放在第三个物理磁盘上,或与输入放在同一物理磁盘上。您希望尽可能减少 I/O 争用。

可能还有一个商业(即付费)程序可以进行分类。开发一个能够有效地对巨大文本文件进行排序的程序是一项艰巨的任务。如果你能花几百美元买一些东西,如果你的时间有价值的话,你可能就赚到了钱。

如果您不能使用现成的程序,那么 . 。 。

如果您的文本位于多个较小的文件中,则问题更容易解决。首先对每个文件进行排序,从这些文件中删除重复项,然后写入已删除重复项的已排序临时文件。然后运行简单的 n 路合并,将文件合并到一个已删除重复项的输出文件中。

如果您有一个文件,则首先将尽可能多的行读入内存,对这些行进行排序,删除重复项,然后写入临时文件。您对整个大文件继续执行此操作。完成后,您将获得一些已排序的临时文件,然后可以合并这些文件。

在伪代码中,它看起来像这样:

fileNumber = 0
while not end-of-input
    load as many lines as you can into a list
    sort the list
    filename = "file"+fileNumber
    write sorted list to filename, optionally removing duplicates
    fileNumber = fileNumber + 1

您实际上不必从临时文件中删除重复项,但如果您的唯一数据实际上仅占总数的 10%,则不将重复项输出到临时文件将节省大量时间。

写入所有临时文件后,您需要合并它们。根据您的描述,我认为您从文件中读取的每个块将包含大约 2000 万行。因此您可能有 25 个临时文件可供使用。

您现在需要进行 k 路合并。这是通过创建优先级队列来完成的。您打开每个文件,读取每个文件的第一行,并将其连同对它来自的文件的引用一起放入队列中。然后,从队列中取出最小的项目并将其写入输出文件。要删除重复项,您需要跟踪输出的前一行,如果新行与前一行相同,则不会输出新行。

输出该行后,您可以从刚刚输出的文件中读取下一行,并将该行添加到优先级队列中。继续这种方式,直到清空所有文件。

我不久前发表了一系列文章。它使用了我上面描述的技术。它唯一不做的就是删除重复项,但这是对输出临时文件的方法和最终输出方法的简单修改。即使没有优化,程序的性能也相当好。它不会创造任何速度记录,但它应该能够在不到 12 小时的时间内对 5 亿行进行排序并删除重复项。考虑到第二遍仅处理总数据的一小部分(因为您从临时文件中删除了重复项),可能要少得多。

为了加快程序速度,您可以做的一件事是对较小的块进行操作,并在将下一个块加载到内存中时在后台线程中对一个块进行排序。您最终不得不处理更多的临时文件,但这确实不是问题。堆操作稍微慢一些,但是通过将输入和输出与排序重叠来重新获得额外的时间是不够的。您最终基本上免费获得 I/O。在典型的硬盘速度下,加载 500 GB 需要大约两个半到三个小时。

看看该系列文章。这是许多不同的文章,大部分是小文章,可以引导您完成我描述的整个过程,并且它提供了工作代码。我很乐意回答您对此可能提出的任何问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

删除大文本文件中的所有重复项 的相关文章

  • 用 OpenCL C 编写快速线性系统求解器

    我正在编写一个 OpenCL 内核 它将涉及求解线性系统 目前我的内核太慢了 提高线性系统部分的性能似乎是一个不错的起点 我还应该注意 我并没有尝试使我的线性求解器并行 我正在研究的问题在宏观层面上已经是令人尴尬的并行 以下是我编写的 C
  • android.R.layout.simple_list_item_1是什么?

    在我看到的所有示例中 他们在创建 ArrayAdapter 时仅使用 android R layout simple list item 1 android R layout simple list item 1是什么 它只是一个名为sim
  • 通过命令行增加Java中的MaxPermSize内存

    您能否解释一下如何增加此 PermSpace 大小 我正在使用 Gate 应用程序并加载大量数据和大量插件 不幸的是每次运行后都会出现有关内存不足 maxPermSpace 的错误 我到处搜索 但我找不到如何通过命令行增加这个大小 或者可能
  • ClassNotFoundException:在嵌入了 cxf 依赖项的 OSGi 包中找不到 org.glassfish.jersey.internal.RuntimeDelegateImpl

    这与jax rs 2 0 更改默认实现 https stackoverflow com questions 17366266 jax rs 2 0 change default implementation我有一个 OSGi 包 其中包含
  • 在 Linq 查询中使用动态列名称

    foreach Dimension dimensions in Enum GetValues typeof Dimension var r new ReferenceTable dimensions referenceItems List
  • 将旧的 Unity 代码升级到 Unity 5

    在触发按钮上播放动画的代码似乎不起作用 我在 Youtube 上看到了一个视频 内容很简单animation Play 它可以在该视频上运行 但我无法让它在我的计算机上运行 我做错了什么还是团结改变了它 请帮助我在网上找不到解决方案 所有
  • AWS Java SDK 中 DynamoDB v2 的迁移详细信息?

    有没有人对新的命名空间进行了更改 com amazonaws services dynamodbv2 以及 AWS Java SDK 1 4 2 及更高版本 中 DynamoDB 的接口 本地二级指数的发布显然需要根据1 4 2 发行说明
  • IntelliJ IDEA 中的项目语言级别是多少?

    我正在使用 Java 7 SDK 和 IntelliJ IDEA IDE java version 1 7 0 11 Java TM SE Runtime Environment build 1 7 0 11 b21 Java HotSpo
  • 当分配返回 0 时,具有空异常规范的运算符 new 调用构造函数

    我有以下声明 void operator new size t s PersistentMemory m throw return m gt allocatePersistentMemory s 我正在测试启动时的内存耗尽 这会导致m gt
  • 我的代码哪里有泄漏?

    下面是我的代码 它打开一个 XML 文件 old xml 过滤无效字符并写入另一个 XML 文件 abc xml 最后 我将再次加载 XML abc xml 当执行以下行时 出现异常 表示 xml 文件被另一个进程使用 xDoc Load
  • Rx 在不同的线程上生产和消费

    我试图通过此处的示例代码来简化我的问题 我有一个生产者线程不断地输入数据 并且我尝试在批次之间添加时间延迟来对其进行批处理 以便 UI 有时间渲染它 但结果并不如预期 生产者和消费者似乎在同一个线程上 我不希望批处理缓冲区在正在生成的线程上
  • 如何为信号量中等待的线程提供优先级?

    我使用信号量来限制访问函数的线程数量 我希望接下来要唤醒的线程应该由我将给出的某个优先级选择 而不是默认信号量唤醒它们的方式 我们怎样才能做到这一点 这是实现 class MyMathUtil2 implements Runnable do
  • 快速将文本附加到文本框

    我有一个BackgroundWorker正在发布消息的线程 使用BeginInvoke在 GUI 中的文本框中 方法 write debug text 在文本框中显示文本使用AppendText并将文本写入Console 外观上是这样的Ba
  • CompletableFuture 的多个 thenAccept 块的执行顺序是什么

    所以我有一个返回a的方法CompletableFuture 在返回之前 此方法添加一个块thenAccept这是在之后执行的CompletableFuture完成 此方法的调用者还添加了另一个块thenAccept 显然 这可以通过多个链式
  • 删除子类中的注释?

    我有一个子类 需要一个注释 在删除的父类中声明 做这个的最好方式是什么 public class Parent MyAnnoation String foobar public class Child extends Parent here
  • 从数据库配置中的连接字符串中删除 SSIS 密码

    我有一个 SSIS 包 它使用 SQL 服务器中的 SSIS 配置表来检索 OLE DB 连接管理器的连接字符串属性 问题是我还需要相同的连接字符串来调用使用实体框架的程序集 我尝试访问连接管理器连接字符串属性 但 SSIS 总是删除密码
  • 如何使用实体框架设置连接字符串

    我将 EF6 与 MySQL 结合使用 并有一个用于多个数据库的模型 我希望能够在我的表单中设置连接设置 如何以编程方式设置模型的连接字符串 你应该使用EntityConnectionFactory这就是您所需要的 public strin
  • DbContext.SaveChangesAsync 异常处理

    当搭建新的脚手架时ApiController通过 Visual Studio 2013 中的异步操作和实体框架支持 某些方法可以包装DbContext SaveChangesAsync https msdn microsoft com en
  • 获取给定字符串日期中该月的最后一天

    我的输入字符串日期如下 String date 1 13 2012 我得到的月份如下 SimpleDateFormat dateFormat new SimpleDateFormat MM dd yyyy Date convertedDat
  • 是否有与 pdl2(或 Devel::REPL)中的 perl 调试器“x”等效的东西?

    我在用pdl2 the PDL http p3rl org PDLshell 也作为我的默认 Perl 交互式 shell 它加载所有不错的插件Devel REPL http search cpan org perldoc Devel 3a

随机推荐