我有一种文件格式(fastq格式),它将一个整数字符串编码为一个字符串,其中每个整数由带有偏移量的ascii代码表示。不幸的是,有两种常用的编码,一种偏移量为33,另一种偏移量为64.我通常有几个1亿个字符串,长度为80-150,可以从一个偏移量转换到另一个偏移量。我可以用来做这类事情的最简单的代码是:
def phred64ToStdqual(qualin):
return(''.join([chr(ord(x)-31) for x in qualin]))
这很好用,但速度不是很快。对于100万个字符串,我的机器大约需要4秒钟。如果我改用使用几个dicts进行翻译,我可以将其缩短到大约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 :(得分: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有一个能够非常快速地执行此操作的函数:maketrans和translate。你可能不会比以下更快:
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)