2013-03-21 13 views
6

Come posso usare pd.read_csv() per pezzo in modo iterativo attraverso un file e mantenere il DTYPE e altre meta-informazioni come se ho letto in tutta la set di dati in una sola volta?Get tipi dataframe dedurre in modo iterativo utilizzando chunksize

ho bisogno di leggere in un insieme di dati che è troppo grande per entrare nella memoria. Vorrei importare il file usando pd.read_csv e quindi aggiungere immediatamente il blocco in un HDFStore. Tuttavia, l'inferenza del tipo di dati non sa nulla dei blocchi successivi.

Se il primo blocco memorizzato nella tabella contiene solo int e un chunk successivo contiene un float, verrà sollevata un'eccezione. Quindi ho bisogno di prima iterare attraverso il dataframe usando read_csv e mantenere ilpiù alto di tipo dedotto. Inoltre, per i tipi di oggetto, ho bisogno di mantenere la lunghezza massima in quanto questi verranno memorizzati come stringhe nella tabella.

C'è un modo pandonico di conservare solo queste informazioni senza leggere nell'intero dataset?

risposta

8

Non pensavo che sarebbe stato così intuitivo, altrimenti non avrei postato la domanda. Ma ancora una volta, i panda rendono le cose un gioco da ragazzi. Tuttavia, mantenere la questione in quanto queste informazioni potrebbe essere utile per gli altri che lavorano con dati di grandi dimensioni:

In [1]: chunker = pd.read_csv('DATASET.csv', chunksize=500, header=0) 

# Store the dtypes of each chunk into a list and convert it to a dataframe: 

In [2]: dtypes = pd.DataFrame([chunk.dtypes for chunk in chunker]) 

In [3]: dtypes.values[:5] 
Out[3]: 
array([[int64, int64, int64, object, int64, int64, int64, int64], 
     [int64, int64, int64, int64, int64, int64, int64, int64], 
     [int64, int64, int64, int64, int64, int64, int64, int64], 
     [int64, int64, int64, int64, int64, int64, int64, int64], 
     [int64, int64, int64, int64, int64, int64, int64, int64]], dtype=object) 

# Very cool that I can take the max of these data types and it will preserve the hierarchy: 

In [4]: dtypes.max().values 
Out[4]: array([int64, int64, int64, object, int64, int64, int64, int64], dtype=object) 

# I can now store the above into a dictionary: 

types = dtypes.max().to_dict() 

# And pass it into pd.read_csv fo the second run: 

chunker = pd.read_csv('tree_prop_dset.csv', dtype=types, chunksize=500) 
+0

si potrebbe anche usare skiprows = un elenco di righe da saltare, e lo hanno saltare ogni riga 1-9 così ur campionamento solo ogni 10 righe, sarebbe molto più veloce (e probabilmente ottieni la risposta che vuoi), penso che dovrai generare da solo le righe saltate – Jeff

+0

@Jeff Come otterresti questo senza conoscere il numero totale di righe nel csv, che comporterebbe la lettura di tutto in – Luke

+3

Si dovrebbe anche considerare di scegliere il massimo dtypes dopo ogni iterazione del blocco, invece di archiviare tutti i tipi e di ridurre alla fine. Ad esempio, un CSV con righe da 2 MM e una dimensione del blocco pari a 500, risulterebbe in 400.000 righe nel frame! – jastr

Problemi correlati