Funciones de transposición Numpy velocidad y casos de uso

Entonces, ¿por qué la transposición NumPy .T más rápida que np.transpose() ?

 b = np.arange(10) #Transpose .T t=b.reshape(2,5).T #Transpose function t = np.transpose(b.reshape(2,5)) #Transpose function without wrapper t = b.reshape(2,5).transpose() 

Hice un timeit de ambos en Jupyter:

 %timeit -n 1000 b.reshape(2,5).T 1000 loops, best of 3: 391 ns per loop %timeit -n 1000 np.transpose(b.reshape(2,5)) 1000 loops, best of 3: 600 ns per loop %timeit -n 1000 b.reshape(2,5).transpose() 1000 loops, best of 3: 422 ns per loop 

y para comprobar la capacidad de escalonamiento hice una matriz más grande:

 b = np.arange( 100000000) %timeit -n 1000 b.reshape(10000,10000).T 1000 loops, best of 3: 390 ns per loop %timeit -n 1000 np.transpose(b.reshape(10000,10000)) 1000 loops, best of 3: 611 ns per loop %timeit -n 1000 b.reshape(10000,10000).transpose() 1000 loops, best of 3: 435 ns per loop 

En ambos casos, el método .T es aproximadamente 2 .transpose() más rápido que el envoltorio y un poco más rápido que usar .transpose() ¿por qué es esto? ¿Hay un caso de uso donde np.transpose sería mejor?

Una razón podría ser que np.transpose(a) simplemente llama a.transpose() internamente, mientras que a.transpose() es más directo. En la fuente tienes:

 def transpose(a, axes=None): return _wrapfunc(a, 'transpose', axes) 

Donde _wrapfunc a su vez es solo :

 def _wrapfunc(obj, method, *args, **kwds): try: return getattr(obj, method)(*args, **kwds) except (AttributeError, TypeError): return _wrapit(obj, method, *args, **kwds) 

Esto se asigna a getattr(a, 'transpose') en este caso. _wrapfunc funciones de nivel de módulo utilizan _wrapfunc para acceder a métodos, generalmente de la clase ndarray o de la clase del primer argumento.

(Nota: .T es lo mismo que .transpose() , excepto que la matriz se devuelve si tiene <2 dimensiones).