我正在从基因组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()
文件本身是2.6Gb,但是当我试图搁置它时,正在生成一个> 100Gb的文件,而且我的计算机会抛出一些关于内存不足和启动磁盘已满的投诉。这似乎只发生在我尝试在OSX Yosemite下运行时,在Ubuntu上它按预期工作。有什么建议为什么这不起作用?我正在使用Python 3.4.2
答案 0 :(得分:2)
通过import dbm; print(dbm.whichdb('your_file.db')
验证dbm使用的接口.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()
众所周知,如果应用程序在更新后崩溃而不调用数据库close
,则dbm数据库会碎片化。我认为这是你的情况。现在您可能还没有大文件中的重要数据,但将来您可以按gdbm.reorganize()
对数据库进行碎片整理。
答案 1 :(得分:0)
我遇到了同样的问题:在一个带有大约4兆字节数据的架子的macOS系统上,磁盘上的巨大容量增加到了29千兆字节!这显然是因为我一遍又一遍地更新了货架上的相同键值对。
由于我的搁架基于GNU dbm,我能够使用他关于重组的提示。这是在几秒钟内将搁置文件恢复到正常大小的代码:
import dbm
db = dbm.open(shelfFileName, 'w')
db.reorganize()
db.close()
我不确定这种技术是否适用于其他(非GNU)dbms。要测试dbm系统,请记住@hynekcer显示的代码:
import dbm
print( dbm.whichdb(shelfFileName) )
如果您的系统使用GNU dbm,则应输出'dbm.gnu'(这是旧gdbm的新名称)。