6

整数の文字列を文字列としてエンコードするファイル形式(fastq形式)があります。各整数は、オフセット付きのASCIIコードで表されます。残念ながら、一般的に使用されているエンコーディングは2つあります。1つはオフセットが33で、もう1つはオフセットが64です。通常、1つのオフセットから別のオフセットに変換する長さ80〜150の文字列が1億個あります。この種のことを行うために私が思いつくことができる最も単純なコードは次のとおりです。

def phred64ToStdqual(qualin):
    return(''.join([chr(ord(x)-31) for x in qualin]))

これは問題なく機能しますが、特に高速ではありません。100万本の弦の場合、私のマシンでは約4秒かかります。いくつかのdictを使用して翻訳を行うように変更すると、これを約2秒に短縮できます。

ctoi = {}
itoc = {}
for i in xrange(127):
    itoc[i]=chr(i)
    ctoi[chr(i)]=i

def phred64ToStdqual2(qualin):
    return(''.join([itoc[ctoi[x]-31] for x in qualin]))

やみくもにcythonの下を走ると、1秒弱になります。
経営幹部レベルのように見えますが、これは単にintにキャストし、減算してから、charにキャストするだけです。私はこれを書いていませんが、かなり速いと思います。これをPythonまたはcythonバージョンでより適切にコーディングする方法を含むヒントは、非常に役立ちます。

ありがとう、

ショーン

4

1 に答える 1

4

urllib.quoteのコードを見ると、あなたがしていることに似た何かがあります。次のようになります。

_map = {}
def phred64ToStdqual2(qualin):
    if not _map:
        for i in range(31, 127):
            _map[chr(i)] = chr(i - 31)
    return ''.join(map(_map.__getitem__, qualin))

上記の関数は、マッピングが同じ長さでない場合に機能することに注意してください(urllib.quoteでは、'%'->'%25'を取る必要があります。

しかし実際には、すべての翻訳が同じ長さであるため、Pythonにはこれを非常に迅速に実行する関数maketranstranslateがあります。あなたはおそらく以下よりもはるかに速くなることはありません:

import string
_trans = None
def phred64ToStdqual4(qualin):
    global _trans
    if not _trans:
        _trans = string.maketrans(''.join(chr(i) for i in range(31, 127)), ''.join(chr(i) for i in range(127 - 31)))
    return qualin.translate(_trans)
于 2010-09-27T16:48:40.020 に答える