2016-11-20 6 views
1

私は私がやろうとしている仕事に利用できることのほとんどは32 GBのメモリを持つシステムで、持っている:私はコード化するいくつかのコードを持っているMemoryError例外()

$ more /proc/meminfo 
MemFree:  29535136 kB 
MemAvailable: 30789956 kB 
... 

をベクトルに文字列中の文字:

#!/usr/bin/env python                          

import os 
import sys 
import numpy as np 
from Bio import SeqIO 
import errno 
import gzip 
import shutil 

seq_encoding = {'A' : [1, 0, 0, 0], 
       'C' : [0, 1, 0, 0], 
       'G' : [0, 0, 1, 0], 
       'T' : [0, 0, 0, 1], 
       'N' : [0, 0, 0, 0]} 

sequence_chunk_length = 200 

def sequence_split_by_length(seq, n): 
    """                              
    A generator to divide a sequence into chunks of n characters and return             
    the base array.                           
    """ 
    while seq: 
     yield [seq_encoding[base] for base in seq[:n].upper()] 
     seq = seq[n:] 

def encode_chromosome(name, length): 
    enc_records = [] 
    fasta_fn = os.path.join(fasta_directory, name + '.fa') 
    fasta_fh = open(fasta_fn, "rU") 
    for record in SeqIO.parse(fasta_fh, "fasta"): 
     for chunk in sequence_split_by_length(str(record.seq), sequence_chunk_length): 
      enc_records.extend(np.asarray(chunk)) 
    fasta_fh.close() 
    enc_arr = np.asarray(enc_records) 

# ... some more code not relevant to exception ... 

エンコーディングはラインで失敗します。ここでは

enc_arr = np.asarray(enc_records) 

はスローの関連する部分であります例外:

Traceback (most recent call last): 
    File "./encode_sequences.py", line 95, in <module> 
    res = encode_chromosome(chromosome_name, sequence_chunk_length) 
    File "./encode_sequences.py", line 78, in encode_chromosome 
    enc_arr = np.asarray(enc_records) 
    ... 
MemoryError 

エンコードされるデータ構造は、約1 GBです。これは、このシステムで使用可能な空きメモリに収まるようです。

PythonリストをNumpy配列に変換するための代替の方法や手順がありますか?のようなNumpyメソッドを使用したMemoryErrorの例外を回避するのに役立ちますか?

+0

Pythonプロセスで実際に使用されているメモリ量を確認する必要があります:[Pythonスクリプトはどれくらいのメモリを使用しているか知っています](http://stackoverflow.com/questions/1240581/python-script-knows-how-much -memory-its-using) –

+0

'np.asarray'はここの唯一のオブジェクトではありません。その行に達する前に' SeqIO.parse'や 'enc_records'自体の' chunk'のような多くのオブジェクトがあります。 – Kasramvd

+0

また、 'np.asarray'を使用すると、配列のデフォルトのデータ型が考慮されます。通常は、必要以上に多くなります。メモリを節約するために、手動で適切なタイプを指定することができます。たとえば 'int64'の代わりに' int8'などです。 – Kasramvd

答えて

0

これは簡単な修正する必要があります:代わりに、デフォルトの整数DTYPEの

  • 使用DTYPE int8

    enc_records = [] 
    for record in SeqIO.parse(fasta_fh, "fasta"): 
        for chunk in sequence_split_by_length(str(record.seq), sequence_chunk_length): 
         enc_records.append(np.asarray(chunk, dtype=np.int8)) 
    enc_arr = np.vstack(enc_record) 
    

    私は2つのことを変更しました。デフォルトのnumpy整数は、プラットフォームによって32または64ビットですが、int8は8ビットのみです。

  • (1x4)ベクトルではなく、リスト内で2D配列(200x4)を収集します。numpy配列は小さな配列に対して大きなメモリオーバーヘッドを持つためです。