43718

[code]

    $ input_A
      @ID_1
      aaaa
      +
      nnnn
      @ID_2
      bbbb
      +
      nnnn
      ...
      @ID_50000000
      zzzz
      +
      nnnn
    
    $ inputB
      ID_832-aaa
      ID_12020-aaa-bbb
      ID_1-nnn-nnn
      ID_9999-ddd-aaa-ccc
      ID_2-xxx-xxx
      ...
      ID_20000000-aaa
    
[/code]

上記のような2つのファイルから、一致したinputBのID情報とinputAのID下の配列情報を取得したいと考えています。  
どちらも2000万〜5000万件程度あります。  
inputAの配列とIDはbiopythonというモジュールを使用して取得させ、下記のような処理を行いました。  
しかし、配列数が多いためか処理時間がかかってしまい、数千万件処理するのに数百時間かかる見込みで実用的ではありません。  
現実的な処理時間でこのような処理を行うにはどうすればよいでしょうか。  
よろしくお願いします。

[code]

    for a in seqIO.parse(inputA, 'fastq'):
        for b in inputB:
            if a.id == b.split('-')[0]
                result = ">" + str(b) + str(q.seq) + '\n'
    
[/code]

下記のようなOutputを想定しています。

[code]

    $ result
      >ID_1-nnn-nnn
      aaaa
      >ID_2-xxx-xxx
      bbbb
      ...
      >ID_50000000-aaa-bbb-ccc
      zzzz
    
[/code]

* * *

追記  
inputBのID番号(先頭から-
まで)と、inputAのID(@より後ろ)が一致したinputBの行(resultの>行)と、その下にinputAの@の下の行を引用したファイルをresultとして作成しようとしています。  
@ID_50000000の@はミスです。修正しました。  
inputAの+行とその下は不要です。  
inputAの@行は重複なし、inputBのID(ID_X)は重複ありですが、行全体(ID_X-abc-abc)は重複なしです。  
pythonのバージョンは2.7.10を使用しています。


CC BY-SA 4.0
2018-05-02T02:36:55.650
43716
2018-05-02T09:27:51.993
2018-05-02T05:59:13.597
22885
22885
question
python
pythonで一致したIDを取得する処理の高速化


辞書オブジェクトを使うことで解決します。  
（inputA の ID に重複がないことを前提としています。）

[code]

    dict = {}
    
    for a in seqIO.parse(inputA, 'fastq'):
        dict[a.id] = a
    
    for b in inputB:
        bid = b.split('-')[0]
        if bid in dict
            result = ">" + str(b) + str(dict[bid].seq) + '\n'
    
[/code]

現在の手法では inputA をループしている中で inputB をループしているため、計算量は `O( inputA * inputB )` となります。

これに対し、辞書を使うと inputA の内容を辞書に格納するループが `O( inputA )`、 inputB の内容で辞書を探すループが `O(
inputB )` となり、全体で `O( inputA + inputB )` となります。  
inputA と inputB
はどちらも1000万のオーダーとのことなので、この変更により、ロジック的にはざっくり1000万倍ほど高速化すると期待できます。  
（どこか別のところがボトルネックになります。IOとか。）

よろしくお願いします。


CC BY-SA 4.0
2018-05-02T03:40:32.637
43718
2018-05-02T03:50:53.437
2018-05-02T03:50:53.437
28340
28340
43716
answer