微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

计算字符串中两个字母对的最快方法

如何解决计算字符串中两个字母对的最快方法

计算字符串中两个字母对的数量(即 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,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”将计算为 2 表示“WW”,而 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,1,1]
,

有一个 numpy 函数,np.char.count()。但它似乎比 str.count() 慢得多。


%timeit counts = np.array([np.char.count(seq,pair) for pair in pairs]) 

1.79 ms ± 32.4 µs per loop (mean ± std. dev. of 7 runs,1000 loops each)
,

由于速度至关重要,以下是不同方法的比较:

import numpy as np
import itertools
from collections import Counter

seq = 'MRNLAIIPARSGSKGLKDKNIKLLSGKPLLAYTIEAARESGLFGEIMVSTDSQEYAD'\
      'IAKQWGANVPFLRSNELSNDTASSWDVVKEVIEGYKNLGTEFDTVVLLQPTSPLRTS'\
      'IEGYKIMKEKDANFVVGVCEMDHSPLWANTLPEDLSMENFIRPEVVKMPRQSIPTYY'\
      'RINGALYIVKVDYLMRTSDIYGERSIASVMRKENSIDIDNQMDFTIAEVLISERSKK'

chars = list('ACDEFGHIKLMNPQRSTVWY')
pairs = [''.join(pair) for pair in itertools.product(chars,chars)]


def countpairs1():
    return np.array([seq.count(pair) for pair in pairs])

%timeit counts = countpairs1()
144 µs ± 1.02 µs per loop (mean ± std. dev. of 7 runs,10000 loops each)


def countpairs2():
    counted = Counter(a+b for a,seq[1:]))
    return np.array([counted[pair] for pair in pairs])

%timeit counts = countpairs2()
102 µs ± 729 ns per loop (mean ± std. dev. of 7 runs,10000 loops each)


def countpairs3():
    return np.array([np.char.count(seq,pair) for pair in pairs])

%timeit counts = countpairs3()
1.65 ms ± 4.62 µs per loop (mean ± std. dev. of 7 runs,1000 loops each)

显然,最好/最快的方法是Counter

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?