这可以并行化吗?

时间:2011-07-06 21:47:05

标签: python perl r hadoop parallel-processing

我有一个巨大的制表符分隔文件。 (作为行的10,000个受试者和作为列的> 100万个测定)。 我有一个映射文件,其中包含与100万列中的每一列相关的信息。 我需要针对每个主题,对于每个分析,(对于每个单元格)查看映射文件并为其获取一些值并替换现有值。

在Python或Perl中,我必须读取每一行,将其拆分并在映射文件中查找每个单元格。

在R中,我可以一次读取每列,并且所有行都可以从映射文件中获取信息。

无论哪种方式,循环遍历每一行或每列的整个过程都需要花费大量时间,因为每个单元格查找都需要完成。

有没有办法可以并行化这个?我应该如何思考是否要将其并行化并使其更快?

另外,我有兴趣学习如何在map / reduce风格中解决这个问题吗?

示例数据文件如下:(制表符分隔)

ID  S1  S2  S3  S4  S5  
1   AA  AB  BA  BB  AB  
2   BA  BB  AB  AA  AA  
3   BA  AB  AB  AB  AB  
4   BA  AB  AB  BB  AA  
5   AA  AB  BA  BB  AB  
6   AA  BB  AB  AA  AA  

映射文件如下:

SID  Al_A  Al_B    
S1    A     C  
S2    G     T  
S3    C     A  
S4    G     T  
S5    A     C  

因此,在数据文件中,在每个单元格中,对于每个A和B,必须在映射文件中进行查找以查看A映射到的内容(来自Al_A列)以及B映射到的内容(来自Al_B专栏)。

2 个答案:

答案 0 :(得分:5)

简单并行

python parse.py assays.txt | python lookup.py mapping.txt | python reformat.py >result.txt

parse.py读取“10,000个主题作为行和> 100万个分析作为列”的“化验”文件它解析并将数据写入stdout。

lookup.py读取“为它获取一些值”映射以填充内部字典。它读取stdin数据,查找并将结果写入stdout。

reformat.py读取stdin并重新格式化它以写入最终报告,该报告似乎反映了输入结构。

虽然这不是“令人尴尬地”并行,但它确实将工作分解为一些平行的并行步骤。它非常强大,可以节省一些时间


然而,您可能想要的是反映问题令人尴尬的并行性质的东西。有10,000 * 1,000,000 == 100亿个人值,所有这些值似乎完全独立。

另一种(更复杂的)方法就是这样。这取决于http://docs.python.org/library/multiprocessing.html

  1. 一个简单的阅读器Process对输入文件进行分区,将记录写入 n 不同的Queue。这意味着每个Queue获得10,000 / n 条记录。 n 可以是10到100之间的大数。是的。 100个队列,每个队列获得100条记录。如果他们等待安排在您服务器上的微小核心上,那也没关系。核心将100%忙碌。这是件好事。

  2. 每个 n Queue都由工作人员Process提供服务,工作人员为记录中的每个化验进行查找并将结果记录放入输出Queue。您可以将 n 调整为各种值,以查看会发生什么。在某些时候,更多的工人会减慢速度。很难预测那个级别在哪里,所以试验。

  3. 输出Queue由工作人员Process读取,它只是将输出文件格式化为队列中的输出文件。

  4. 这意味着您需要某种“Assay”对象,您可以从输入文件序列化并入队到Python

答案 1 :(得分:1)

据我所知,您的每个数据单元都独立于其他数据单元,因此有一种非常直接的方法可以在不更改任何预先存在的代码的情况下对其进行并行化。您所要做的就是使用split命令行工具等命令预处理数据文件。然后,与您拥有的任何预先存在的代码并行处理每个文件。最后,最后把它们全部放在一起。

以下是您可能要执行的命令示例:

split -l 100 data_file.tsv data_
ls data_* | xargs -L 1 perl your_processing_file.pl
cat output_* > total_output
rm output_*

这假设您的脚本将获取名为data_ $ x的文件并创建一个输出名称为output_ $ x的新文件,您可能需要稍微更改它。

这实际上是一种非常常见的并行化问题的方法。