2016-12-22 11 views
1

私は2つのcsvファイルを持っています(そのうち1つは.tabです)。どちらも2列の数字列です。私の仕事は、最初のファイルの各行を調べ、それが2番目のファイルのいずれかの行と一致するかどうかを確認することです。もしそうなら、私は出力csvファイルに空白行を表示します。それ以外の場合は、出力のcsvファイルに 'R、R'を出力します。私の現在のアルゴリズムは以下のない:第二のファイル(二つの整数それぞれ)の各行は、2次元アレイでこれらの二つの整数の位置に移動非常に大きなcsvファイルを検索するにはどうすればよいですか?

  1. スキャン(SO整数2と3であれば、私は
  2. 最初のファイルの各行を調べ、各行の2つの整数の位置が配列内の値1であるかどうかを確認し、その出力を3番目のcsvファイルに出力します。

残念ながら、csvファイルは非常に大きいので、これを実行すると即座に "MemoryError:"が表示されます。大規模なCSVファイルをスキャンするための代替手段は何ですか?

私はジュピターノートを使用しています。私のコード:

import csv 
import numpy 

def SNP(): 
    thelines = numpy.ndarray((6639,524525)) 
    tempint = 0 
    tempint2 = 0 
    with open("SL05_AO_RO.tab") as tsv: 
     for line in csv.reader(tsv, dialect="excel-tab"): 
      tempint = int(line[0]) 
      tempint2 = int(line[1]) 
      thelines[tempint,tempint2] = 1 
    return thelines 

def common_sites(): 
    tempint = 0 
    tempint2 = 0 
    temparray = SNP() 
    print('Checkpoint.') 
    with open('output_SL05.csv', 'w', newline='') as fp: 
     with open("covbreadth_common_sites.csv") as tsv: 
      for line in csv.reader(tsv, dialect="excel-tab"): 
       tempint = int(line[0]) 
       tempint2 = int(line[1]) 
       if temparray[tempint,tempint2] == 1: 
        a = csv.writer(fp, delimiter=',') 
        data = [['','']] 
        a.writerows(data) 
       else: 
        a = csv.writer(fp, delimiter=',') 
        data = [['R','R']] 
        a.writerows(data) 
    print('Done.') 
    return 

common_sites() 

ファイル: https://drive.google.com/file/d/0B5v-nJeoVouHUjlJelZtV01KWFU/view?usp=sharinghttps://drive.google.com/file/d/0B5v-nJeoVouHSDI4a2hQWEh3S3c/view?usp=sharing

+3

問題はこれでしょう: 'numpy.ndarray((6639,524525))'。あなたは 'ndarray'コンストラクタを使うべきではありません。' array'または 'zeros'を使うべきです。しかし、関係なく、6639 * 524525の 'np.float64'の配列を作成しています。少なくとも6639 * 524525 * 1e-9 *(64/8)' == '27.8585718'ギグが必要です。しかし、あなたのファイルを見ると、それらは**ちょっと**です。おそらくそれらを両方ともメモリにロードし、1つのセットを作り、次にもう一方を繰り返し、メンバーシップのセットをチェックしてください。あなたが得ることができる可能性のあるサイズの大きさである配列を使うことは、これを達成するためにおそらく最小限のメモリ効率的な方法でしょう。 –

答えて

2

あなたしているデータセットは本当に大きくはありませんが、それは比較的まばらです。問題の原因となっているデータを格納するために疎構造を使用していません。
ちょうど見たデータを格納するタプルのsetを使用し、そのset上のルックアップは例えば、O(1)です:

In [1]: 
    import csv 
    with open("SL05_AO_RO.tab") as tsv: 
     seen = set(map(tuple, csv.reader(tsv, dialect="excel-tab"))) 
    with open("covbreadth_common_sites.csv") as tsv: 
     common = [line for line in csv.reader(tsv, dialect="excel-tab") if tuple(line) in seen] 
    common[:10] 
Out[1]: 
    [['1049', '7280'], ['1073', '39198'], ['1073', '39218'], ['1073', '39224'], ['1073', '39233'], 
    ['1098', '661'], ['1098', '841'], ['1103', '15100'], ['1103', '15107'], ['1103', '28210']] 

10 loops, best of 3: 150 ms per loop 

In [2]: 
    len(common), len(seen) 
Out[2]: 
    (190, 138205) 
1

I have 2 csv files (well, one of them is .tab), both of them with 2 columns of numbers. My job is to go through each row of the first file, and see if it matches any of the rows in the second file. If it does, I print a blank line to my output csv file. Otherwise, I print 'R,R' to the output csv file.

import numpy as np 

f1 = np.loadtxt('SL05_AO_RO.tab') 
f2 = np.loadtxt('covbreadth_common_sites.csv') 

f1.sort(axis=0) 
f2.sort(axis=0) 

i, j = 0, 0 
while i < f1.shape[0]: 
    while j < f2.shape[0] and f1[i][0] > f2[j][0]: 
     j += 1 
    while j < f2.shape[0] and f1[i][0] == f2[j][0] and f1[i][1] > f2[j][1]: 
     j += 1 
    if j < f2.shape[0] and np.array_equal(f1[i], f2[j]): 
     print() 
    else: 
     print('R,R') 
    i += 1 
  1. ロードデータをndarrayにメモリ使用量を最適化するために
  2. データをソート
  3. ソート済み配列で一致するものを見つける

合計複雑度はO(n*log(n) + m*log(m))です.nとmは入力ファイルのサイズです。

set()を使用しても一意のエントリあたりのメモリ使用量は減少しないため、大きなデータセットで使用することはお勧めしません。

関連する問題