numpy转置和翻转索引哪个更快?

7 投票
1 回答
5901 浏览
提问于 2025-04-17 13:59

我有一个动态规划算法(修改版的Needleman-Wunsch),它需要进行两次相同的基本计算,不过第二次计算的方向是正交的。举个例子,从一个给定的单元格 (i,j) 在矩阵 scoreMatrix 中,我想从 (i,j) 的“上方”计算一个值,同时也想从 (i,j) 的“左侧”计算一个值。为了重用代码,我写了一个函数,第一次我传入参数 i,j,scoreMatrix,而第二次我传入 j,i,scoreMatrix.transpose()。下面是这个代码的一个简化版本:

def calculateGapCost(i,j,scoreMatrix,gapcost):
  return scoreMatrix[i-1,j] - gapcost

...
gapLeft = calculateGapCost(i,j,scoreMatrix,gapcost)
gapUp = calculateGapCost(j,i,scoreMatrix.transpose(),gapcost)
...

我意识到,我可以传入一个函数,在获取 scoreMatrix 中的值时,第一次传入参数 (i,j),而在第二次时把它们反转为 (j,i),这样就不需要每次都转置矩阵了。

def passThrough(i,j,matrix):
  return matrix[i,j]

def flipIndices(i,j,matrix):
  return matrix[j,i]

def calculateGapCost(i,j,scoreMatrix,gapcost,retrieveValue):
  return retrieveValue(i-1,j,scoreMatrix) - gapcost

...
gapLeft = calculateGapCost(i,j,scoreMatrix,gapcost,passThrough)
gapUp = calculateGapCost(j,i,scoreMatrix,gapcost,flipIndices)
...

不过,如果numpy的转置功能使用了一些我不知道的特性,能够在很少的操作下完成转置,那么转置可能实际上比我这个传递参数的函数更快。有人能告诉我哪个更快吗?或者有没有我没想到的更好的方法?

实际的方法会调用 retrieveValue 三次,并涉及到两个会被引用的矩阵(如果使用转置的方法,这两个矩阵也会被转置)。

1 个回答

10

在NumPy中,转置操作会返回一个形状不同的视图,并且有不同的步幅。但它并不会改变数据本身。

所以,你会发现这两种方法的性能基本相同,因为从本质上来说,它们是完全一样的。

不过,唯一能确定的方法就是对这两种方法进行性能测试。

撰写回答