2010-09-27 47 views
6

我有一個文件格式(fastq格式),它將整數字符串編碼爲字符串,其中每個整數由具有偏移量的ascii代碼表示。不幸的是,有兩種常見的編碼方式,一種是偏移量爲33,另一種是偏移量爲64.我通常有幾個1億個80-150的字符串將一個偏移量轉換爲另一個偏移量。最簡單的代碼,我可以拿出來做這種事情是:將ascii編碼轉換爲int並在Python中快速返回(快速)

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

這工作得很好,但它並不特別快。對於1百萬個字符串,我的機器大約需要4秒。如果我改變使用幾個字來做翻譯,我可以把它降低到大約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秒。
它看起來像在C級,這只是一個強制轉換爲int,減去然後轉換爲char。我沒有寫這篇文章,但我猜測它快了很多。任何提示,包括如何更好地在python甚至是cython版本中編寫代碼來做到這一點都會很有幫助。

感謝,

肖恩

+0

嘗試用替換'[]'' ()'使用生成器而不是創建和放棄列表。我懷疑它會做出一個巨大的差異,但它應該做一些。 – RichieHindle 2010-09-27 16:25:58

+0

用()替換[],()與任何最近的Python都是多餘的 – pixelbeat 2010-09-27 16:30:29

+0

好主意,但字符串連接需要一個列表,我相信,所以不會直接工作,我不認爲。 – seandavi 2010-09-27 16:38:06

回答

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) 
+0

謝謝,邁克。在上述同一臺機器上,這是一個快速的0.1秒,並且對於我的目的來說足夠快。我將堅持phred64ToStdqual4()如上所列.... – seandavi 2010-09-27 17:43:09