2012-03-22 21 views

risposta

13

Il modo più veloce è quello di utilizzare il metodo numpy.fromstring:

>>> import numpy 
>>> data = "1|234|4456|789" 
>>> numpy.fromstring(data, dtype=int, sep="|") 
array([ 1, 234, 4456, 789]) 
+2

+1: sicuramente il più veloce ancora. – DSM

+0

perché non ci ho pensato ..: P – wim

+0

Grazie mille .. Abbastanza efficiente dal calcolo del tempo @bernie .. :) –

5

Prova questo:

import numpy as np 
s = '1|234|4456|789' 
array = np.array([int(x) for x in s.split('|')]) 

... Supponendo che i numeri sono tutti interi. in caso contrario, sostituire int con float nello snippet di codice precedente.

EDIT 1:

In alternativa, si può fare questo, sarà solo creare uno lista intermedio (quello generato da split()):

array = np.array(s.split('|'), dtype=int) 

EDIT 2:

E ancora un altro modo, possibilmente più veloce (grazie per tutti i commenti, ragazzi!):

array = np.fromiter(s.split("|"), dtype=int) 
+0

Il problema con questo i s che genera un elenco in memoria di tutte le parti della stringa. Se ci sono veramente 50 milioni di parti, c'è un sacco di memoria in più per una lista temporanea. –

+0

@AdamMihalcin che dipende in realtà dalla versione di Python in uso. In Python 3, l'elenco viene valutato pigramente e non vengono creati elenchi intermedi. Inoltre, il PO ha detto che la funzione sarebbe stata chiamata 50 milioni di volte, non che ci siano 50 milioni di elementi nella lista. –

+1

@AdamMihalcin Anche se si utilizza 'imap' o un'espressione di generatore? Oscar - Su Python 3, la comprensione dell'elenco creerà comunque una lista intermedia. – agf

7

@jterrace vince un (1) Internet.

Nelle misure seguenti il ​​codice di esempio è stato abbreviato per consentire ai test di adattarsi su una riga senza scorrere, ove possibile.

Per chi non ha familiarità con timeitthe -s flag allows you to specify a bit of code which will only be executed once.


Il modo più veloce e meno ingombra è quello di utilizzare numpy.fromstring come jterrace suggerito:

python -mtimeit -s"import numpy;s='1|2'" "numpy.fromstring(s,dtype=int,sep='|')" 
100000 loops, best of 3: 1.85 usec per loop 

I seguenti tre esempi utilizzano string.split in combinazione con un altro strumento.

string.split con numpy.fromiter

python -mtimeit -s"import numpy;s='1|2'" "numpy.fromiter(s.split('|'),dtype=int)" 
100000 loops, best of 3: 2.24 usec per loop 

string.split con int() Cast tramite generatore-espressione

python -mtimeit -s"import numpy;s='1|2'" "numpy.array(int(x) for x in s.split('|'))" 
100000 loops, best of 3: 3.12 usec per loop 

string.split con NumPy array di tipo int

python -mtimeit -s"import numpy;s='1|2'" "numpy.array(s.split('|'),dtype=int)" 
100000 loops, best of 3: 9.22 usec per loop 
+5

+1 Adoro vincere internet :) – jterrace

+0

spiegazione molto migliore sulla differenza di velocità! –

Problemi correlati