2

我有一个非常大的文件(包含 dbSNP ID),包含 100 万行,每行包含一个字符串,另一个更大的文件 (.vcf) 包含 6 亿行,每行包含 7-8 列。

我想在较大的文件中找到较小文件的每一行的第一次出现,使我的程序的蛮力复杂度为 1,000,000 * 600,000,000 次。我想要一种更快、更少内存密集型的方式来执行此操作。我是 python 中的多处理或并行编程的新手,我不确定如何在不使用任何一个的情况下解决这个问题。

numpy我已经尝试使用和pandas库对两个文件的较小子集执行类似的操作:

import numpy as np
import pandas as pd

BigFile = pd.Series(arrayOfRowsOfBiggerFile)
SmallFile = pd.Series(arrayOfRowsOfSmallerFile)
FinalList = SmallFile.map(lambda x: np.where(A==x)[0][0]).tolist()

这需要很长时间才能执行,我确信可以使用 python 多处理很好地处理。

4

2 回答 2

4

如果我理解正确,您实际上是在执行一个join操作:您希望 VCF 中的所有行,其键(在本例中为 RSID)出现在您的“较小”文件中。在此处查看文档:https ://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.join.html

你的代码看起来像这样:

dbsnp = pd.read_csv('path/to/dbsnp', index_col='rsid', ...)
rsids_of_interest = pd.read_csv('path/to/smaller_file', ...)

subset_of_dbsnp = dbsnp.join(rsids_of_interest, how='inner', ...)
于 2019-03-12T14:02:23.210 回答
2

假设您只想根据变体列表提取 .vcf 文件的子集,您可以

( 1 ) 使用@OronNavon 建议的解决方案。它至少应该适用于较小的文件。对于较大的文件大小,它可能需要大量的计算资源,如果您可以访问集群,这不一定是个问题。如果您在家用 PC 上运行它,您可能会耗尽内存。您可以通过动态读取文件来解决它,但这仍然是一个缓慢的过程。此外,您可能会丢失包含所有元数据的 .vcf 标头,因此如果您需要它(或 .vcf 功能),您应该单独添加它。

( 2 ) 将 .vcf 文件拆分成块,如果需要,可以并行运行。尽管它的效率不会那么高,因为您只有 rsID 而不是较小文件中的位置。

( 3 ) 使用Plink这是一个独立的包,但它可以快速/高效地完成工作。(这就是我会做的。)

于 2019-03-12T15:07:22.103 回答