0

给定两个数据序列(长度相等)和每个数据点的质量值,我想根据给定的评分矩阵计算相似度得分。

向量化以下循环的最有效方法是什么:

score = 0
for i in xrange(len(seq1)):
    score += similarity[seq1[i], seq2[i], qual1[i], qual2[i]]

similarity是一个4维浮点数组,shape=(32, 32, 100, 100); seq1, seq2,qual1qual2是等长的一维 int 数组(顺序为 1000 - 40000)。

4

2 回答 2

3

这不应该只是工作(tm)吗?

>>> score = 0
>>> for i in xrange(len(seq1)):
        score += similarity[seq1[i], seq2[i], qual1[i], qual2[i]]
...     
>>> score
498.71792400493433
>>> similarity[seq1,seq2, qual1, qual2].sum()
498.71792400493433

代码:

import numpy as np

similarity = np.random.random((32, 32, 100, 100))
n = 1000
seq1, seq2, qual1, qual2 = [np.random.randint(0, s, n) for s in similarity.shape]

def slow():
    score = 0
    for i in xrange(len(seq1)):
        score += similarity[seq1[i], seq2[i], qual1[i], qual2[i]]
    return score

def fast():
    return similarity[seq1, seq2, qual1, qual2].sum()

给出:

>>> timeit slow()
100 loops, best of 3: 3.59 ms per loop
>>> timeit fast()
10000 loops, best of 3: 143 us per loop
>>> np.allclose(slow(),fast())
True
于 2013-05-02T15:26:43.487 回答
0

这个怎么样?

score = numpy.sum(map(similarity.__getitem__, zip(seq1, seq2, qual1, qual2)))

当然,您也可以尝试使用 itertools imap 和 izip。zip 是必要的,因为__getitem__需要一个元组而不是四个数字......也许可以通过查看 itertools 模块的较暗角落以某种方式改进。

于 2013-05-02T15:31:13.507 回答