对于2Gb文本文件,搁架字典大小> 100Gb

jma*_*991 5 python bioinformatics shelve out-of-memory

我正在从基因组FASTA文件创建序列的搁置文件:

# Import necessary libraries
import shelve
from Bio import SeqIO

# Create dictionary of genomic sequences
genome = {}
with open("Mus_musculus.GRCm38.dna.primary_assembly.fa") as handle:
    for record in SeqIO.parse(handle, "fasta"):
        genome[str(record.id)] = str(record.seq)

# Shelve genome sequences
myShelve = shelve.open("Mus_musculus.GRCm38.dna.primary_assembly.db")
myShelve.update(genome)
myShelve.close()
Run Code Online (Sandbox Code Playgroud)

该文件本身是2.6Gb,但是当我试图搁置它时,正在生成一个> 100Gb的文件,而且我的计算机将抛出一些关于内存不足和启动磁盘已满的投诉.这似乎只发生在我尝试在OSX Yosemite下运行时,在Ubuntu上它按预期工作.有什么建议为什么这不起作用?我正在使用Python 3.4.2

hyn*_*cer 3

验证 dbm 使用的接口是import dbm; print(dbm.whichdb('your_file.db')shelve 使用的文件格式取决于系统及其接口上可用的最佳安装的二进制包。最新的是gdbm,而dumb如果没有找到二进制文件,则是后备解决方案,ndbm介于两者之间。
https://docs.python.org/3/library/shelve.html
https://docs.python.org/3/library/dbm.html

如果丢失所有用于文件系统缓存的内存,则将所有数据都存储在内存中并不有利。按较小的块进行更新效果更好。如果一项一项更新,我什至没有看到速度减慢。

myShelve = shelve.open("Mus_musculus.GRCm38.dna.primary_assembly.db")
with open("Mus_musculus.GRCm38.dna.primary_assembly.fa") as handle:
    for i, record in enumerate(SeqIO.parse(handle, "fasta")):
        myShelve.update([(str(record.id), str(record.seq))])
myShelve.close()
Run Code Online (Sandbox Code Playgroud)

众所周知,如果应用程序在更新后未调用数据库而崩溃,则 dbm 数据库会变得碎片化close。我认为这就是你的情况。现在您的大文件中可能还没有重要数据,但将来您可以通过gdbm.reorganize().