为什么 numpy.ndarray.T 比 numpy.transpose(numpy.ndarray) 快得多?

wor*_*ise 8 python performance numpy

最近我遇到有人使用numpy.transpose而不是numpy.ndarray.T. 我很好奇,所以我计时了:

from timeit import timeit
import numpy as np

array1015 = np.random.rand(10,15)

def nptrans():
    np.transpose(array1015)

def npt():
    array1015.T

print(timeit(nptrans))
print(timeit(npt))
Run Code Online (Sandbox Code Playgroud)

结果是:

np.transpose: 1.25864219666

np.ndarray.T: 0.720939874649
Run Code Online (Sandbox Code Playgroud)

为什么?他们不应该在幕后做同样的事情吗?也许np.transpose是在进行某种错误检查或减慢速度?

MSe*_*ert 7

首先,操作速度如此之快,如果在那里进行优化并不重要!

\n\n
%timeit nptrans()  # 100000 loops, best of 3: 2.11 \xc2\xb5s per loop\n%timeit npt()      # 1000000 loops, best of 3: 905 ns per loop\n
Run Code Online (Sandbox Code Playgroud)\n\n

优化这个没有意义,除非你会做数百万次转置而不做其他事情。即使添加它们也会慢得多:

\n\n
%timeit array1015 + array1015  # 100000 loops, best of 3: 3.55 \xc2\xb5s per loop\n
Run Code Online (Sandbox Code Playgroud)\n\n

而且加法应该非常非常快!

\n\n

然而,有一些开销np.transpose不存在于np.ndarray.T

\n\n
    \n
  • np.transpose最后调用对象.transpose方法,这意味着它必须查找对象的方法并调用它。
  • \n
  • 为了避免重复代码,开发人员将实际调用该方法的函数打包在单独的函数中。=> 又一个函数调用。
  • \n
\n\n

因此,您看到的开销是 2 个函数调用和一个 -call 的结果getattr。该np.transpose函数实际上是 python 的,所以你可以很容易地看到开销(我删除了注释):

\n\n
def transpose(a, axes=None):\n    return _wrapfunc(a, \'transpose\', axes)  # extra function call\n\ndef _wrapfunc(obj, method, *args, **kwds):\n    try:\n        return getattr(obj, method)(*args, **kwds)  # here it finally calls ndarray.transpose()\n    except (AttributeError, TypeError):\n        return _wrapit(obj, method, *args, **kwds)\n
Run Code Online (Sandbox Code Playgroud)\n