2013-02-20 2 views
2

동일한 키가 큰 사전 가입 :내가 지금처럼 파이썬 사전을 포함 약 10 대용량 파일이

dict1: 
    { 
     'PRO-HIS-MET': { 
      'A': ([1,2,3],[4,5,6],[7,8,9]), 
      'B': ([5,2],[6],[8,9]), 
      'C': ([3],[4],[7,8])}, 
     'TRP-MET-GLN': { 
      'F': ([-5,-4,1123],[-7,-11,2],[-636,-405])} 
    } 

    dict2: 
    { 
     'PRO-HIS-MET': { 
      'J': ([-657], [7,-20,3], [-8,-85,15])} 

     'TRP-MET-GLN':{ 
      'K': ([1,2,3],[4,50,6],[7,80,9]), 
      'L': ([5,20],[60,80],[8,9])} 
    } 

기본적으로 그들은 사전의 모든 사전이 있습니다. 각 파일의 크기는 약 1GB입니다 (위는 데이터의 예입니다). 어쨌든, 내가 뭘하고 싶은 10 개 개의 사전을 함께 조인 : 나는 작은 파일에 다음 코드를 시도

final: 
    { 
     'PRO-HIS-MET': { 
      'A': ([1,2,3],[4,5,6],[7,8,9]), 
      'B': ([5,2],[6],[8,9]), 
      'C': ([3],[4],[7,8]) 
      'J': ([-657], [7,-20,3], [-8,-85,15])}, 
     'TRP-MET-GLN': { 
      'F': ([-5,-4,1123],[-7,-11,2],[-636,-405]) 
      'K': ([1,2,3],[4,50,6],[7,80,9]), 
      'L': ([5,20],[60,80],[8,9])} 
    } 

을하고 그것을 잘 작동합니다 : 그러나

import csv 
    import collections 
    d1 = {} 
    d2 = {} 
    final = collections.defaultdict(dict) 

    for key, val in csv.reader(open('filehere.txt')): 
     d1[key] = eval(val) 
    for key, val in csv.reader(open('filehere2.txt')): 
     d2[key] = eval(val) 

    for key in d1: 
     final[key].update(d1[key]) 
    for key in d2: 
     final[key].update(d2[key]) 

    out = csv.writer(open('out.txt', 'w')) 
    for k, v in final.items(): 
     out.writerow([k, v]) 

I가 있음을하려고하면 내 1GB 파일 메모리의 최종 사전은 물론 d1과 d2를 유지함으로써 메모리가 부족합니다.

  1. 난 그냥 그 비교, 분할 된 사전에서 키를로드하고 같은 사람이 여러 사전에 발견 될 경우 바로 값을 결합 할 수있는 방법이 있나요 :

    나는 몇 가지 아이디어를 가지고?
  2. 사전을 하나의 거대한 파일로 병합하는 대신 (나중에 메모리 문제가 발생할 수 있음) 데이터를 병합 한 후 하나의 키에 대한 모든 값을 포함하는 많은 개별 파일을 만들 수 있습니까? 예를 들어, 위의 데이터를 그냥 것 :

    pro-his-met.txt: 
    'PRO-HIS-MET': { 
        'A': ([1,2,3],[4,5,6],[7,8,9]), 
        'B': ([5,2],[6],[8,9]), 
        'C': ([3],[4],[7,8]) 
        'J': ([-657], [7,-20,3], [-8,-85,15])} 
    trp-met-gln.txt: 
    'TRP-MET-GLN': { 
        'F': ([-5,-4,1123],[-7,-11,2],[-636,-405]) 
        'K': ([1,2,3],[4,50,6],[7,80,9]), 
        'L': ([5,20],[60,80],[8,9])} 
    

내가 생물학 너무 많은 프로그래밍 경험이없는 (당신은 위의 데이터는 생물 정보학 문제를 나타냅니다 짐작 할 수있다) 그래서 어떤 도움 많이 감사하겠습니다!

+0

당신이하지 않은 이유가 있나요 데이터베이스 시스템을 사용하고 있습니까? 이런 식으로 조작해야 할 엄청난 양의 데이터가있는 것 같습니다. –

+0

대부분의 이유로 모든 종류의 데이터베이스에 대한 나의 경험이 부족합니다. 파이썬 사전을 db로 변환 할 때 나는 무엇을 제안합니까? – deckardk

+0

'eval'을 사용한다는 사실은 게으른 해결책을 얻는 것을 어렵게 만듭니다. @Voo가 말하듯이 데이터베이스를 사용하십시오. – nneonneo

답변

1

shelve 모듈은 매우 사용하기 쉬운 Python 데이터베이스입니다. 그것은 실제 데이터베이스만큼 강력하지는 않지만 (@ Voo의 대답 참조) 큰 사전을 조작하는 트릭을 수행 할 것입니다.

우선, 선반을 당신의 사전에서 만들 :

import shelve 
s = shelve.open('filehere.db', flag='n', protocol=-1, writeback=False) 
for key, val in csv.reader(open('filehere.txt')): 
    s[key] = eval(val) 
s.close() 

을 이제 깔끔하게 모든 것을 보류 한 것을, 당신이 효율적으로 사전에 작동 할 수 있습니다

import shelve 
import itertools 
s = shelve.open('final.db', flag='c', protocol=-1, writeback=False) 
s1 = shelve.open('file1.db', flag='r') 
s2 = shelve.open('file2.db', flag='r') 
for key, val in itertools.chain(s1.iteritems(), s2.iteritems()): 
    d = s.get(key, {}) 
    d.update(val) 
    s[key] = d # force write 
s.close() 
+0

굉장합니다, 그 순간을위한 좋은 단기 해결책처럼 보입니다. 나는 확실히 미래에 대한 데이터베이스에 대해 한 두 가지를 배워야 할 것입니다. – deckardk

+0

재미있는 모듈이 있습니다. 나중에 참조 할 때 유용 할 수 있습니다. – Voo

+0

@nneonneo,이 빠른 구현 시도했지만 값을 업데이트하는 작동하지 않는 것. "AttributeError : 'NoneType'객체에 'update'속성이 없습니다."라는 오류가 있습니다. 존재하지 않는 키를 업데이트하는 것처럼 보이기 때문입니다. 이 문제를 해결하기 전에 defaultdict를 사용 했었지만 여기서 어떻게 진행해야하는지 모릅니다. – deckardk

1

개인적으로 이것은 데이터베이스가 해결하기 위해 발명 된 문제의 원형과 같습니다. 예. 파일을 보관하고 성능 최적화를 위해 파일을 메모리에 매핑하고 OS가 스와핑을 처리하도록 할 수는 있지만이 작업은 실제로 복잡하고 어렵습니다.

수백만 시간의 작업 시간을두고 DB를 처리 할 수 ​​있다면 왜이 모든 노력을 기울여야합니까? 그러면 더 효율적으로 정보를 쿼리하는 것이 훨씬 쉬워집니다.

오라클 DB는 10GB 이상의 데이터를 아무 문제없이 저장하는 것을 보았습니다. 포스트 그레 (postgre)도이 문제를 잘 처리 할 것입니다. 좋은 점은 ORM을 사용하면 멋진 데이터를 추상화 할 수 있다는 것입니다. 세부 사항을 멀리하고 나중에 필요할 경우 걱정할 필요가 있습니다.

또한 생물 정보학은 나의 전문 분야가 아니지만 나는 생물 정보학에 맞는 구체적인 해결책이있을 것이라고 확신한다. 아마도 그 중 하나가 완벽한 적합 일 것인가?

+0

실제로 내가하는 일처럼 들립니다. 나는 데이터베이스에 대한 경험이 거의 없다. 내가 무엇을 사용하도록 제안 하는가? 약간의 배경을 알려 드리겠습니다. 원본 데이터는 위의 정보로 다시 정렬 된 BioPython 코드를 사용하여 생성 된 6GB의 큰 사전입니다. 이것이 내가이 데이터 구조를 고수했기 때문에 새로운 것을 배울 수있어서 기뻤습니다. – deckardk

+0

@deckardk 개인적으로 나는 데이터베이스 모조의 대부분을 추상화 한 ORM (Object-Relational mapping) 인 [SQLAlchemy] (http://www.sqlalchemy.org/)에 대한 자습서부터 살펴 보겠습니다. 귀하의 데이터베이스에 대해서는 아마도 튜토리얼에 사용되는 sqlite 대신 PostgreSQL을 사용하고 싶을 것입니다. (그러나 이러한 세부 사항은 추상화되어 있기 때문에 간단하게 sqlite로 시작할 수 있으며 성능이 Postgre 후에). – Voo

+0

감사합니다. @Voo. 튜토리얼을보고 데이터베이스에 대한 새로운 것을 배우려고합니다. – deckardk

0

이 개념은 효과가 있습니다.

나는 당신이 키의 일부를 할 때마다 파일에 대해 여러 번 패스하는 것을 고려할 것이다. 그 결과를 저장하십시오.

예 : 한 번에 모든 키의 고유 한 첫 번째 문자 목록을 만든 다음 각 문자를 처리하면 새 출력 파일로 전달됩니다. 단순한 알파벳 데이터라면 논리적 인 선택은 알파벳의 각 문자가있는 루프 일 것입니다.

예 :"p"패스에서 'PRO-HIS-MET'를 처리 할 것입니다.

그러면 모든 파일의 모든 결과가 결합됩니다.

개발자 인 경우 이전 종류의 상호 작용을 처리 할 수있는 경우 이전 답변의 데이터베이스 아이디어가 가장 좋은 방법 일 수 있습니다. 이 아이디어는 레코드를 삽입하고 업데이트 한 다음 결과를 SQL 문으로 쿼리하는 2 수준 구조를 만드는 것을 의미합니다.

+0

파일 시스템 솔루션을 확장 가능하고 효율적으로 만들기까지하면 아마도 파일을 주소 공간에 매핑하고 OS가 스와핑에 대해 걱정하게 할 것입니다. * 수백만 개의 자습서가있는 사소한 DB 설정보다 훨씬 복잡합니다. – Voo

+0

포스터는 개발자가 아닙니다 (DB 기술이 없음을 의미 함) 스크립팅 기술이 있다는 사실에 기반하여 접근 할 수있는 방법을 제안했습니다. 게시글에 명시된 바와 같이 DB 솔루션이 가장 좋은 방법이라고 생각합니다. – DarrenMB

+0

나는 의견이 맞지 않습니다. 저는이 게시물이 생물 정보학에서 일하고 있다는 것을 말하고 있습니다. 즉, 10GB는 아마도 그가 얻을 수있는 데이터의 양에 대한 작은 하한이고 FS로 다소 효율적으로 주어진 문제를 구현한다는 것입니다. ORM 튜토리얼을 읽는 것보다 훨씬 복잡합니다. 지옥에 가면 경험있는 개발자가 하루 정도 걸릴 것입니다. – Voo

관련 문제