2016-05-24 22 views
7

Sto generando una matrice grande (100x100, chiamiamola X) con numeri casuali, con numpy.matrix() in modo da avere un numpy.ndarray.Differenze delle funzioni di trasposizione in python

mi sono chiesto se ci sono differenze tra le due operazioni:

  1. numpy.transpose (X)
  2. XT

Ho misurato il tempo di ogni operazione in un ciclo con un intervallo di 1000 e sembra che XT sia significativamente più veloce di numpy.transpose (X)

Aggiunto Benchmark:

Per una matrice 100x100 ho ottenuto i seguenti risultati con XT e numpy.tranpose (X)

In un loop di 10.000 intervalli:

  • 7421/10.000: XT più veloce
  • 1256/10,000: numpy.transpose (X) più veloce
  • 1323/10,000: Stesso tempo di calcolo o la differenza troppo piccola per determinare

Aggiunta la codice qui sotto

import numpy as np 
    import time 

    np_transpose_count = 0 
    T_transpose_count = 0 
    equal_count = 0 

    for i in range(10000): 
     Se = np.random.rand(100,100) 

     tic1 =time.clock() 
     ST_T = Se.T 
     toc1=time.clock() 

     tic2 =time.clock() 
     ST_np = np.transpose(Se) 
     toc2=time.clock() 

     if (toc1-tic1) < (toc2-tic2): 
      T_transpose_count+=1 
     elif (toc1-tic1) > (toc2-tic2): 
      np_transpose_count+=1 
     else: 
      equal_count+=1 

    print(T_transpose_count, np_transpose_count, equal_count) 

migliori saluti whir

+0

Interessante. Non capisco le unità del tuo benchmark. Potresti aggiornare per dire? Sul mio sistema, sembra che X.T sia 20-30% più veloce di X.transpose() (usando% timeit su 100x100 o 10000x10000 array). – user20160

+2

Inoltre, 'np.transpose (X)' è il 120-130% più lento di 'x.T' sul mio sistema. Forse c'è una piccola quantità di overhead extra per la funzione call ('x.transpose()' è una funzione mentre 'x.T' non lo è). 'np.transpose()' è una funzione python con un po 'di codice wrapping, quindi c'è un overhead extra lì. – user20160

risposta

5

Utilizzando ipython %timeit magia ottengo:

In [218]: X=np.ones((100,100)) 

In [219]: timeit X.T 
1000000 loops, best of 3: 379 ns per loop 

In [220]: timeit X.transpose() 
1000000 loops, best of 3: 470 ns per loop 

In [221]: timeit np.transpose(X) 
1000000 loops, best of 3: 993 ns per loop 

In [222]: timeit X+1 
10000 loops, best of 3: 21.6 µs per loop 

Quindi sì, .T è più veloce, e la funzione più lento. Ma confrontare quei tempi con il tempo di una semplice aggiunta

o una copia o fetta

In [223]: timeit X.copy() 
100000 loops, best of 3: 10.8 µs per loop 

In [224]: timeit X[:] 
1000000 loops, best of 3: 465 ns per loop 

Trasposizione in tutte le sue forme restituisce un nuovo oggetto array, con il nuovo shape e strides, ma con un buffer di dati condivisi (Guarda il dizionario .__array_interface__ per vederlo). Quindi ci vuole circa lo stesso tempo di altre azioni che restituiscono un view. Ma nessuna delle funzioni di trasposizione fa una copia dei dati o scorre attraverso di essa. Quindi le differenze di orario sono solo il risultato di una telefonata.

Sempre con ipython magia

np.transpose?? 
def transpose(a, axes=None): 
    try: 
     transpose = a.transpose 
    except AttributeError: 
     return _wrapit(a, 'transpose', axes) 
    return transpose(axes) 

Così np.function(X) finisce per chiamare X.transpose().

Dovrei controllare il codice numpy, ma ricordo che lo .T è implementato come attribute (non proprio uguale a property). Sospetto che sia più veloce perché non utilizza il parametro axes e pertanto salva una o due chiamate di funzione C.

+0

Grazie per la tua risposta dettagliata. E 'stato molto utile per la mia comprensione di questo. – Whir