我有一个序列信息文件,所以文件结构如下,
[SEQUENCE ID]
atgctagctagatcga
[SEQUENCE ID]
agatcgatggctagatc
我一直在做的是比较文件以查看共享的序列ID,这很简单,但现在我想拉出与ID相关的实际序列。我正在使用的文件很大(10 GB +),因此使用字典或任何涉及将所有行读入系统内存的内容都已用完。
基本上代码的目的是如果在文件2中找不到文件1中的序列ID,则返回文件1中序列ID之后的行。任何提示?
答案 0 :(得分:2)
所以你只需要N行和N + 1行?在这种情况下,以两行的块读取文件。然后,您始终可以访问序列ID和序列。
from itertools import izip
with open('data.txt', 'r') as f:
for line1, line2 in izip(*(iter(f),) * 2):
print line1, line2
答案 1 :(得分:0)
简短回答:您将不得不使用第三方Python库来保持其中一个数据序列可以比O(n)更好地搜索。
如果未对它们进行排序,则必须至少对其中一个文件进行排序。想一想: 我从文件1中获取序列ID - 并检查它是否不存在于file2中,我将读取所有文件 - 比读取文件一次更加可行。
比 - 比排序更好,有一个数据结构能够以一种方式保存光盘上的排序数据以提供快速搜索,并且仍然能够增长 - 这样做也很有用,这也有助于排序,因为你在第一步中所要做的就是读取文件2中的条目,然后插入这个不断增长的磁盘持久化数据结构。
虽然你肯定可以推出自己的数据结构来做到这一点,但我建议使用 ZODB - ZOPE的面向对象的DATABSe,带有btree文件夹,然后让你的“ 2行数据“成为您的任务的最小对象。
答案 2 :(得分:0)
假设[SEQUENCE ID]确实适合内存,并且大部分数据实际上在序列行上(与提供的示例不同) - 您可以选择解析文件(问题中的file2),和anotate不仅te [SEQUENCE ID] - 而且是每个这样的标识符的文件位置。这种方法可以让您在不制动当前工作流程的情况下继续(例如,必须了解数据库) :
def get_indexes(filename):
with open(filename, "rt") as file:
sequences = {}
while True:
position = file.tell()
id = file.readline()
if not id:
break()
sequences[id.strip()] = position
# skip corresponding data line:
file.readline()
return sequences
def fetcher(filename1, filename2, sequences):
with open(filename1, "rt") as file1, open(filename2, "rt" as file2):
while True:
id = file.readline()
data = file.readline()
if not id:
break
id = id.strip()
if id in sequences:
# postion file2 reading at the identifier:
file2.seek(sequences[id])
# throw away id:
file2.readline()
data = file.readline()
yield id, data
if __name__== "__main__":
sequences = getindexes("/data/file2")
for id, data in fetcher("/data/file1", "/data/file2", sequences):
print "%s\n%s"% (id, data)