许多文本文件中包含大量数据-如何处理?

33

我有大量数据(几个TB),并且正在积累中...它们包含在许多制表符分隔的文本文件中(每个约30MB)。大部分任务涉及读取数据并根据一系列谓词语句对观测/行进行聚合(求和/平均值+其他转换),然后将输出保存为文本、HDF5或SQLite文件等。我通常使用R来完成这样的任务,但我担心这可能有点太大了。一些备选解决方案是:

  1. 用C(或Fortran)编写整个程序
  2. 直接将文件(表)导入关系数据库,然后在R或Python中提取块(一些转换不适合纯SQL解决方案)
  3. 用Python编写整个程序

方案3是否是一个坏主意?我知道您可以在Python中包装C例程,但在这种情况下,因为没有计算方面的限制(例如需要进行多次迭代计算的优化例程),我认为I/O可能与计算本身一样成为瓶颈。您是否对进一步考虑或建议有任何建议?谢谢。

编辑 感谢您的回复。关于Hadoop似乎存在着不一致的意见,但无论如何,我没有访问集群的权限(尽管我可以使用几台未联网的机器)...


1
很好的问题,这听起来像是我在处理生物序列数据时遇到的相同问题。 - Stedy
8个回答

14

(3) 并不是一个坏主意 - Python 可以轻松地处理 "CSV" 文件(尽管 C 代表逗号,但制表符作为分隔符同样容易处理),当然,在 I/O 操作方面 Python 与其他语言差别不大。至于其他建议,numpy 除了提供快速的计算(根据您的陈述可能并不需要)外,还提供非常方便、灵活的多维数组,这对您的任务可能非常有用;标准库模块 multiprocessing 让您可以利用多个核心来并行化任何容易并行化的任务(这很重要,因为现今的每台机器几乎都有多个核心;-)。


我想我会尝试使用Python、NumPy和multiprocessing... 非常感谢。 - hatmatrix
同意。Python所谓的性能惩罚在现实世界中并不太明显。 - Paul McMillan

14

好的,那么为什么不试试R呢?

  • 您似乎很熟悉R,因此可以快速得到工作代码。
  • 对于具有几GB RAM的标准工作站,每个文件30MB并不算大。
  • 如果您通过colClasses参数指定列的类型,则read.table()read.csv()变体可能非常有效:而不是猜测转换类型,将会有效地处理这些类型。
  • 瓶颈在于从磁盘进行i/o操作,对于所有语言来说都是如此。
  • R有multicore来在具有多个核心的机器上设置并行处理(类似于Python的multiprocessing)。
  • 如果您想要使用“尴尬的并行”结构来解决问题,R有几个适用于数据并行问题的软件包:例如,snowforeach可以部署在一台机器上,也可以部署在一组网络化的机器上。

我认为可以用R来完成,但是我的一部分感觉它不是正确的工具?虽然你包含了所有额外的考虑,它肯定可以被制作出来...我最近开始使用data.frame(scan(filename,what=list(...)))来尝试加快输入速度,但指定colClasses可能只是另一个好主意。谢谢~ - hatmatrix
3
@Stephen 别忘了检查这个线程 https://dev59.com/_XI-5IYBdhLWcg3wsKh4。我需要你快速阅读并理解其中的内容,因为我们需要用R语言处理非常大的数据表格。 - Marek
谢谢!我一直是R用户,但这很有帮助。 - hatmatrix
1
很高兴能够帮助。您可能会发现我的“使用R进行HPC入门”教程幻灯片非常有用。 - Dirk Eddelbuettel
1
十二年后,这仍然是我解决问题的一般方法。除非您可以获得预算来使用像Cloud Dataflow这样的云解决方案。 - Andrew Brēza

6

看看Disco。它是一个轻量级的分布式MapReduce引擎,用大约2000行Erlang编写,但专门为Python开发设计。它不仅支持处理数据,还支持可靠地存储和复制。他们刚刚发布了0.3版本,其中包括索引和数据库层。


谢谢 - 我将继续关注Disco。不过我在数据库层面上找不到太多文档,也许目前MapReduce框架对我的硬件来说不太适用... - hatmatrix
Discodb是一种简易的数据库。它基本上只是一个分布式哈希表,位于ddfs之上。我自己对它了解不多,因为它很新。 - Marcelo Cantos

4

如果你有很多的数据(以TB为单位),那么你需要将读取操作并行化到多个磁盘上,因此最好直接使用Hadoop。

使用Pig或者Hive来查询数据;这两种工具都有广泛的支持用户定义转换的功能,因此你应该能够使用自定义代码实现所需的操作。


4
我在亚马逊的弹性MapReduce上使用R和Hadoop时非常顺利。通过EMR,您只需支付所使用的计算机时间,并且AMZN会负责启动和关闭实例。如何在EMR中构建作业取决于分析工作流程的结构。例如,一个作业所需的所有记录是否完全包含在每个csv文件中,或者您需要从每个csv文件中获取一些位来完成分析?
以下是您可能会发现有用的一些资源:

我在博客文章中提到的问题更多是CPU限制,而不是IO限制。你遇到的问题更多是IO,但加载库和缓存文件的提示可能会有用。

虽然把这个放入/从关系型数据库中似乎很诱人,但我建议仔细考虑是否真正需要所有关系型数据库的开销。如果不需要,那么您可能会创建一个瓶颈和开发挑战,而没有任何真正的回报。


1
非常感谢 - 我想还有一个问题,就是是否值得将数据传输到他们的基础设施中! - hatmatrix

2
如果您有一组机器,可以使用Hadoop Mapreduce并行化应用程序。虽然Hadoop是用Java编写的,但也可以运行Python。您可以查看以下链接以获取有关并行化代码的指针 - PythonWordCount

2

当您说“累积”时,解决方案(2)似乎最适合问题。
在将文件初始加载到数据库后,您只需使用新文件更新数据库(每天、每周?取决于您需要的频率)。

在情况(1)和(3)中,您需要每次处理文件(这是最耗费时间/资源的),除非您找到一种方法来存储结果并使用新文件进行更新。

您可以使用R将文件从csv处理为SQLite数据库。


啊,我明白你的意思了……但是一旦我处理完每个文本文件,我很可能会将结果存储在SQLite文件中,并使用这些结果进行后续分析。我所做的聚合是一种时间平均化(这是纵向数据),因此在分析当前文件时,我不必重新导入以前的文件(这就是为什么MapReduce可能是有意义的原因吧……)。 - hatmatrix

1

是的。你说得对!I/O将占用大部分处理时间。我不建议你使用分布式系统,例如hadoop,来完成这个任务。

你的任务可以在一台适度的工作站上完成。我不是Python专家,但我认为它支持异步编程。 在F#/.Net中,该平台对此有很好的支持。 我曾经执行过一个图像处理作业,在磁盘上加载20K个图像并将它们转换为特征向量只需要几分钟的并行处理。

总之,以并行方式加载和处理数据,并将结果保存在内存中(如果很小)或数据库中(如果很大)。


谢谢 - 我希望如此。我手头只有一些普通的工作站(和一些时间)。 - hatmatrix

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接