2013-05-18 8 views
5

Supponiamo di avere una stringa contenente dati da un DB o un foglio di calcolo in formato separato da virgole.Il modo più veloce per estrarre solo determinati campi da una stringa separata da virgola in Python

Ad esempio:

data = "hello,how,are,you,232.3354,good morning" 

Si supponga che ci sono forse 200 campi in questi "record".

Sono interessato a osservare solo alcuni campi di questo record. Qual è il modo più veloce in Python per arrivare a loro?

Il modo più semplice sarebbe qualcosa di simile:

fields = data.split(",") 
result = [fields[4], fields[12], fields[123]] 

Esiste un modo più veloce per fare questo, avvalendosi del fatto che:

  1. Hai solo bisogno di allocare una lista con 3 elementi e 3 oggetti stringa per il risultato.
  2. si può fermare la scansione della stringa di dati una volta raggiunto campo 123.

Ho cercato di scrivere del codice utilizzando i ripetuti inviti di trovare per saltare le virgole passati ma se l'ultimo campo è troppo lontano lungo la stringa di questo diventa più lento della soluzione split di base.

Sto elaborando diversi milioni di record, quindi qualsiasi accelerazione sarebbe gradita.

+2

Sarà difficile battere il nativo 'str.split()' con una soluzione Python. –

+1

Non ho idea se sia più veloce o meno, ma puoi evitare di dividere l'intera stringa con 'data.split (", ", 124)'. – chepner

+0

sei sicuro che sia un collo di bottiglia nella tua applicazione? Quanto più veloce è necessario per spostare il collo di bottiglia da qualche altra parte nella tua app? – jfs

risposta

0

Se result può essere un tuple invece di una lista, si potrebbe ottenere un po 'di un aumento di velocità (se si sta facendo più chiamate) utilizzando operator.itemgetter:

from operator import itemgetter 
indexer = itemgetter(4,12,123) 
result = indexer(data.split(',')) 

Avresti bisogno di timeit alla realtà vedere se si ottiene una velocità o no però.

1

Non hai intenzione di fare molto meglio che caricare tutto in memoria e quindi eliminare le parti di cui hai bisogno. La mia raccomandazione è la compressione e una libreria migliore.

Come accade, ho un paio di csv di dimensioni ragionevoli in giro (questo è 500k linee).

> import gzip 
> import pandas as pd 
> %timeit pd.read_csv(gzip.open('file.csv.gz')) 
1 loops, best of 3: 545 ms per loop 

L'eliminazione delle colonne è anche piuttosto veloce, non sono sicuro di quale sia il costo maggiore.

> %timeit csv[['col1', 'col2']] 
100 loops, best of 3: 5.5 ms per loop 
Problemi correlati