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).