2014-02-28 9 views
6

큰 단백질 시퀀스 (fasta) 파일 (> 8GB)을 다루고 있으며 내 생각은 키와 값이 될 사전을 만드는 것입니다. 단백질 ID와 서열이어야한다. 큰 파일 (> 8GB)을 읽고 사전에 데이터를 덤프하고 다시로드하는 가장 빠른 방법

지금에 관해서는 나는 (내가 pickle 데이터를 덤프 빠르며 cpickle 데이터를로드 할 빠른 읽기)하고 cpickle로 열려고 다음 pickle를 사용하여 사전에 데이터를 덤프하고 OK (확인)입니다. 그러나 여기에서 가장 중요한 문제는 시간이다. 사전을 작성하고 덤프하는 것은 너무 많은 시간과 메모리를 소비한다 (PC는 8GB 메모리가있다).

파이썬에서 대용량 파일을 처리 할 수있는 더 빠른 옵션이 있습니까?

from Bio import SeqIO 
import pickle,sys 

fastaSeq = {} 
with open('uniref90.fasta') as fasta_file: 
    for seq_record in SeqIO.parse(fasta_file, 'fasta'): 
     header =seq_record.id 
     uniID = header.split('_')[1] 
     seqs = str(seq_record.seq) 
     fastaSeq[uniID] = seqs 

f = open('uniref90.obj', 'wb') 
pickle.dump(fastaSeq, f, pickle.HIGHEST_PROTOCOL) 
f.close() 

로드 사전에 별도의 파이썬 프로그램에서 일부 작업을 수행 :

import cPickle as pickle 
seq_dict = pickle.load(open("uniref90.obj", "rb")) 
for skey in seq_dict.keys(): 
    #doing something 
+0

우선 : 파일이 메모리에 맞지 않습니다.그래서 스와핑은 정말 느립니다. 또한 8GB의 덤프 /로드는 처음에는 그다지 빠르지 않습니다. 파일별로 작업해야합니다. 그렇게하기 위해서는 데이터를 분할해야합니다. 그것은 사소한 일입니다. 나는 ** 적절한 데이터베이스 **를 사용하여 조언. 또한 : 당신에게 "느린"것이 무엇을 의미합니까? 무엇을 성취하려고합니까? – freakish

답변

6

데이터베이스는 내 아들입니다.

import sqlite3 
from Bio import SeqIO 

db = sqlite3.connect("./db") 

c = db.cursor() 
c.execute('''CREATE TABLE IF NOT EXISTS map (k text unique, v text)''') 
db.commit() 


def keys(db): 
    cursor = db.cursor() 
    return cursor.execute("""SELECT k FROM map""").fetchall() 


def get(key, db, default=None): 
    cursor = db.cursor() 
    result = cursor.execute("""SELECT v FROM map WHERE k = ?""", (key,)).fetchone() 
    if result is None: 
     return default 
    return result[0] 


def save(key, value, db): 
    cursor = db.cursor() 
    cursor.execute("""INSERT INTO map VALUES (?,?)""", (key, value)) 
    db.commit() 


with open('uniref90.fasta') as fasta_file: 
    for seq_record in SeqIO.parse(fasta_file, 'fasta'): 
     header = seq_record.id 
     uniID = header.split('_')[1] 
     seqs = str(seq_record.seq) 
     save(uniID, seqs, db) 
+0

큰 데이터 세트를 다루기에 정말 편리한 sqlite3 함수를 배우는 것이 좋고 솔루션을 사용해 주셔서 감사합니다. – Paul85

0

cPickle 제네릭에 대한 지금까지 가장 빠른을 여기에

내 파이썬 데이터를 사전을 만들고 덤프 코드 데이터 구조.

데이터 구조에 의해 부과 된 제약 사항에 따라 더 빠른 JSON 구현 중 하나 인 ujson을 시도하십시오. 부동 소수점 값의 정확성을 유지하기 위해 일부 플래그를 전달해야 할 수 있습니다.

데이터가 일정하다면 numpy.load 변종이 더 빠를 것입니다. 텍스트에서 이진 데이터에 이르는 형식 옵션이 있습니다.

마지막으로 numpy.mmap을 사용하면 데이터를 "로드"하지 않고도 액세스 할 수 있습니다. 즉, 데이터는 액세스 할 때만 RAM에 도달합니다. 그것은 지금까지 가장 빠를 것입니다.

사전이있는 경우 해당 언어는 shelve입니다.

0

아니라, 당신의 문제는 반드시 파이썬으로, 큰 데이터 세트를 처리하는 방법을 정말입니다. 무엇을 시도하든, 메모리에 8GB를 초과하는로드를 원하지는 않습니다. 응용 프로그램을 스왑으로 바꾸고 요소에 액세스하려고 할 때마다 페이지 인/RAM에서 출력합니다.

내가 쉽게 절인 할 수있는 여러 파일에서 실제로 종류의 데이터 집합하는 것 할 줄 방법은, 각각의 파일은 분할 데이터 세트를로드하는 데 시간이 빠르고, 그래서 내장 된 키에 대한 몇 가지 해시 함수를 사용하여 정렬된다. 그런 다음 해시 함수 조건과 일치하는 데이터 집합 만로드하면됩니다.이 데이터 집합은 빠르게 수행되고 키 값을 추출합니다.

그리고 마지막으로 항상 의 C 구현 인 cPickle을 사용하고로드 및 덤프에 더 빨라야합니다 (개인적으로 벤치 마크를 만들지는 않았지만).

N.B : 그 해결책은 어쨌든 포이먼의 데이터베이스입니다. 물론 @ freakish의 제안과 @ Jakob의 데이터베이스 사용 솔루션은 정말 좋은 생각입니다. 필자가 제안하는 해결책은 네트워크 노드 전체에 걸쳐 데이터 집합을 배포하고 여러 서버에 걸쳐 저장소를 배포하는 일반적인 방법입니다.