python - 计算字符串中两个字母对的最快方法
问题描述
计算字符串中两个字母对的数量的最快方法是什么(即 AA、AB、AC 等)?是否可以使用 numpy 来加快计算速度?
我正在使用列表理解str.count()
,但这很慢。
import itertools
seq = 'MRNLAIIPARSGSKGLKDKNIKLLSGKPLLAYTIEAARESGLFGEIMVSTDSQEYAD'\
'IAKQWGANVPFLRSNELSNDTASSWDVVKEVIEGYKNLGTEFDTVVLLQPTSPLRTS'\
'IEGYKIMKEKDANFVVGVCEMDHSPLWANTLPEDLSMENFIRPEVVKMPRQSIPTYY'\
'RINGALYIVKVDYLMRTSDIYGERSIASVMRKENSIDIDNQMDFTIAEVLISERSKK'
chars = list('ACDEFGHIKLMNPQRSTVWY')
pairs = [''.join(pair) for pair in itertools.product(chars, chars)]
print(pairs[:10])
print(len(pairs))
['AA', 'AC', 'AD', 'AE', 'AF', 'AG', 'AH', 'AI', 'AK', 'AL']
400
%timeit counts = np.array([seq.count(pair) for pair in pairs])
231 µs ± 5.88 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
print counts[:10]
[0, 1, 1, 0, 0, 0, 1, 1, 1, 0]
解决方案
如果您不介意在字典中获取计数,则集合中的 Counter 类的处理速度会快 2-3 倍:
from collections import Counter
chars = set('ACDEFGHIKLMNPQRSTVWY')
counts = Counter( a+b for a,b in zip(seq,seq[1:]) if a in chars and b in chars)
print(counts)
Counter({'RS': 4, 'VV': 4, 'SI': 4, 'MR': 3, 'SG': 3, 'LL': 3, 'LS': 3,
'PL': 3, 'IE': 3, 'DI': 3, 'IA': 3, 'AN': 3, 'VK': 3, 'KE': 3,
'EV': 3, 'TS': 3, 'NL': 2, 'LA': 2, 'IP': 2, 'AR': 2, 'SK': 2,
...
这种方法将正确计算重复 3 次或更多次的相同字符的序列(即,“WWW”对于“WW”将计为 2,而 seq.count() 或 re.findall() 仅计为 1)。
请记住,他的 Counter 字典将为 counts['LC'] 返回零,但 counts.items() 将不包含 'LC' 或实际上不在字符串中的任何其他对。
如果需要,您可以在第二步中获得所有理论对的计数:
from itertools import product
chars = 'ACDEFGHIKLMNPQRSTVWY'
print([counts[a+b] for a,b in product(chars,chars)][:10])
[1, 0, 1, 1, 0, 0, 0, 1, 1, 1]
推荐阅读
- ruby-on-rails - 如果定义了变量,则设置变量,如果未定义,则设置 null
- javascript - 在反应代码中调用 .getElementById 后返回 Null
- java - 如何使用 Java 中的 Stanford CoreNLP 提取普通和复杂句子或句子文档(主语、宾语和谓语)的三元组?
- symfony - 无法将 symfony/security 从 4.4.1 更新到 5.0.1
- javascript - HTML 元素没有正确调整大小 - 间距?
- google-oauth - 使用 GoogleWebAuthorizationBroker.AuthorizeAsync 时,用户可以点击错误的电子邮件地址
- javascript - 使用三元运算符消除重复显示的可能性
- html - 所需的 HTML 输入未按预期工作
- machine-learning - sklearn SVM 默认距离测量
- reactjs - 使反应子组件占据全屏