所以,这件事让我很难过!
我正在处理巨大的文本文件,我指的是100Gb+。具体来说,它们在fastq format中。这种格式用于DNA测序数据,由四行记录组成,如下所示:
@REC1
GATTTGGGGTTCAAAGCAGTATCGATCAAATAGTAAATCCATTTGTTCAACTCACAGTTT
+
!''*((((***+))%%%++)(%%%%).1***-+*''))*55CCF>>>>>>CCCCCCC65
@REC2
GATTTGGGGTTCAAAGCAGTATCGATCAAATAGTAAATCCATTTGTTCAACTCACAGTTT
+
!''*((((***+))%%%++)(%%%%).1***-+*''))**55CCF>>>>>>CCCCCCC65
.
.
.
为了这个问题,只需关注标题行,从“@”开始。在
所以,出于QA的目的,我需要比较两个这样的文件。这些文件应该有匹配的头,因此另一个文件中的第一个记录也应该有头文件“@REC1”,下一个记录应该是“@REC2”,依此类推。在我进行大量的下游分析之前,我想确保情况确实如此。
由于文件太大,一个简单的迭代字符串比较会花费很长时间,但是这个QA步骤将运行很多次,我不能再等那么长时间。所以我认为一个更好的方法是从文件中的几个点取样记录,例如每10%的记录。如果记录顺序混乱,我很有可能发现它。
到目前为止,我已经能够通过估计文件大小来处理这些文件,而不是使用python的file.seek()
访问文件中间的一条记录。例如,要访问大约在中间的一条线,我可以:
但现在问题更复杂了,因为我不知道如何在两个文件之间协调,因为字节位置不是文件中行索引的指示符。换句话说,如何访问两个文件中的10567311行,以确保它们是相同的,而不必检查整个文件?在
如有任何建议/提示,不胜感激。可能是并行迭代?但具体怎么办?
谢谢!在
您是否研究过使用
rdiff
命令。RDIF的优点是:
RDIF的缺点是:
参见:http://beerpla.net/2008/05/12/a-better-diff-or-what-to-do-when-gnu-diff-runs-out-of-memory-diff-memory-exhausted/
取样是一种方法,但你得靠运气。另外,Python是执行此项工作的错误工具。您可以使用标准的Unix命令行工具,以仍然相当有效的方式执行不同的操作,并计算出准确的答案:
diff
。如果存在差异,diff
将报告它。在要线性化,可以通过
awk
运行FASTQ文件:要比较一对文件:
^{pr2}$如果有任何差异,
diff
将找到它并告诉您哪个FASTQ记录不同。在{1}你可以直接在两个文件上进行线性化,但是如果你不做线性化的话,那你就可以直接在这两个文件上运行线性化了。在
所以这些是大文件。写入新文件在时间和磁盘空间上都很昂贵。有一种方法可以改进这一点,使用streams。在
如果将
awk
脚本放入一个文件(例如,,linearize_fq.awk
),则可以这样运行它:这对您的100+Gb文件很有用,因为现在您可以通过
bash
process substitutions设置两个Unix文件流,并直接在这些流上运行diff
:或者您可以使用named pipes:
命名管道和进程替换都避免了创建额外(常规)文件的步骤,这对于您的输入可能是一个问题。将100+Gb文件的线性化副本写入磁盘可能需要一段时间,而且这些副本还可能占用您可能没有的磁盘空间。在
使用streams可以解决这两个问题,这使得它们对于以有效的方式处理生物信息学数据集非常有用。在
您可以用Python复制这些方法,但它几乎肯定会运行得慢得多,因为Python在处理像这样的重I/O任务时非常慢。在
在Python中,并行迭代可能是最好的方法。我不知道它的运行速度有多快(快速的SSD可能是加快速度的最佳方法),但由于无论如何,您都必须计算两个文件中的新行数,因此我看不到解决此问题的方法:
这是为python3编写的,其中
zip
返回一个迭代器;在python2中,您需要使用itertools.izip()
。在相关问题 更多 >
编程相关推荐