2016-01-18 10 views
12

Pensavo che la terza opzione avrebbe dovuto essere il modo più veloce per eliminare gli spazi bianchi? Qualcuno può darmi alcune regole generali che dovrei applicare quando lavoro con insiemi di dati di grandi dimensioni? Di solito uso .astype (str) ma chiaramente non vale la pena per le colonne che so già di oggetti. primo sguardoPrestazioni di str.strip per Pandas

%%timeit 
fcr['id'] = fcr['id'].astype(str).map(str.strip) 
10 loops, best of 3: 47.8 ms per loop 

%%timeit 
fcr['id'] = fcr['id'].map(str.strip) 
10 loops, best of 3: 25.2 ms per loop 

%%timeit 
fcr['id'] = fcr['id'].str.strip(' ') 
10 loops, best of 3: 55.5 ms per loop 
+1

forse vale la pena chiedere su [github] (https://github.com/pydata/pandas/issues) perché questo è il caso in quanto questo non è quello che mi aspetterei – EdChum

+1

Sarebbe meglio fare un po ' più profilazione prima di vedere cosa sta causando il relativo rallentamento. In generale i tuoi ultimi due non saranno equivalenti poiché i metodi pandas '.str' tutti 1.) prendono regex o stringhe, 2.) gestiscono i NaN senza far esplodere. Forse vedi come è il sovraccarico di quelli. – TomAugspurger

+1

@TomAugspurger Ho eseguito test su una semplice riga di 30k df: 'df = pd.DataFrame ({'id': ['asds', 'asd', 'asdsa asdasdas']}) df = pd.concat ([ df] * 10000, ignore_index = True) 'e ha osservato la stessa cosa delle temporizzazioni dell'OP – EdChum

risposta

12

Let la differenza tra .map(str.strip) e .str.strip() (secondo e terzo caso).
Pertanto, è necessario capire che cosa fa str.strip() sotto il cofano: in realtà fa un po 'di map(str.strip), ma usa una funzione personalizzata map che gestirà i valori mancanti.
Quindi dato che .str.strip()fa più di .map(str.strip), ci si può aspettare che questo metodo sia sempre più lento (e come hai mostrato, nel tuo caso 2x più lento).

L'utilizzo del metodo .str.strip() presenta vantaggi nella gestione automatica NaN (o nella gestione di altri valori non stringa). Supponiamo che la colonna 'id' contiene un valore NaN:

In [4]: df['id'].map(str.strip) 
... 
TypeError: descriptor 'strip' requires a 'str' object but received a 'float' 

In [5]: df['id'].str.strip() 
Out[5]: 
0     NaN 
1    as asd 
2  asdsa asdasdas 
       ... 
29997    asds 
29998   as asd 
29999 asdsa asdasdas 
Name: id, dtype: object 

Come @EdChum fa notare, è possibile infatti utilizzare map(str.strip)se si è sicuri non si dispone di alcun valore NaN se questa differenza di prestazioni è importante.


Tornando all'altra differenza di fcr['id'].astype(str).map(str.strip). Se sai già che i valori all'interno della serie sono stringhe, fare la chiamata a astype(str) è ovviamente superfluo. Ed è questa chiamata che spiega la differenza:

In [74]: %timeit df['id'].astype(str).map(str.strip) 
100 loops, best of 3: 10.5 ms per loop 

In [75]: %timeit df['id'].astype(str) 
100 loops, best of 3: 5.25 ms per loop 

In [76]: %timeit df['id'].map(str.strip) 
100 loops, best of 3: 5.18 ms per loop 

Si noti che nel caso si dispone di valori non-string (Nan, valori numerici, ...), utilizzando .str.strip() e .astype(str).map(str) sarà non cedere lo stesso risultato:

In [11]: s = pd.Series([' a', 10]) 

In [12]: s.astype(str).map(str.strip) 
Out[12]: 
0  a 
1 10 
dtype: object 

In [13]: s.str.strip() 
Out[13]: 
0  a 
1 NaN 
dtype: object 

come si può vedere, .str.strip() tornerà valori non stringa come NaN, invece di convertirli in stringhe.