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

7

我有一个动态规划算法(改良版 Needleman-Wunsch),需要进行相同的基本计算两次,但第二次计算是在正交方向上完成的。例如,在矩阵 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转置使用了我不知道的某些功能来在几个操作中执行转置,那么transpose实际上可能比我的传递函数想法更快。是否有人可以告诉我哪个会更快(或者是否有我没有想到的更好的方法)?
实际方法将调用“retrieveValue”3次,并涉及到将要引用的2个矩阵(因此如果使用该方法则需要转置)。

你有看过文档吗? - Josh Lee
transpose(转置)如果可能的话只返回一个“视图”——因此它是一项快速操作——也就是说,如果您可以切换数组索引的方式,那么在逐个操作元素时,这可能是最快的方法。 - mgilson
2
使用 timeit 进行测试您的实际数据可能只需要 5 分钟,如果您使用 ipython 并且有 %timeit,则时间会更短。为什么不试一下呢?而不是询问别人去猜测? - abarnert
我猜我不需要进行那些编辑。感谢您的快速回复。根据您所说,mgilson,文档现在非常清晰易懂了,虽然之前我不太确定。 - Todd Gillette
1
@abanert 我不确定这是否是该网站的目的,但我想说,回答这个问题让我从五分钟的研究变成了十秒钟的谷歌搜索。回答简单的问题可以将SO变成一个可搜索的百科全书,我和其他人都很感激。 - Richard Rast
这对缓存优化有什么影响?如果转置只是另一种视图,那么这两种方法是否等效?还是我漏掉了什么?(尽管示例中的函数调用会更慢) - Matt Thompson
1个回答

10
在NumPy中,转置返回一个形状和步幅不同的视图。它不会影响数据。
因此, 你很可能会发现这两种方法的性能相同,因为本质上它们完全相同。
然而,确保性能的唯一方法是对两者进行基准测试。

太好了。我会坚持使用转置,因为它显然是一个更简单的解决方案。谢谢! - Todd Gillette

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接