2010-11-12 27 views
9

Sono nuovo di Python e ho quella che è probabilmente una domanda di base sul modo "migliore" per memorizzare i dati nel mio codice. Qualche consiglio molto apprezzato!Struttura dati più appropriata (Python)

ho una lunga file .csv nel seguente formato:

Scenario,Year,Month,Value 
1,1961,1,0.5 
1,1961,2,0.7 
1,1961,3,0.2 
etc. 

mio scenario Valori di correre da 1 a 100, anno va 1961-1990 e mese va da 1 a 12. Il mio file ha quindi 100 * 29 * 12 = 34800 righe, ciascuna con un valore associato.

Mi piacerebbe leggere questo file in una sorta di struttura dati Python in modo che possa accedere a un "Valore" specificando "Scenario", "Anno" e "Mese". Qual è il modo migliore per farlo per favore (o quali sono le varie opzioni)?

Nella mia testa, penso a questi dati come una sorta di 'numero cuboide' con assi per Scenario, Anno e Mese, in modo che ogni Valore si trovi in ​​coordinate (Scenario, Anno, Mese). Per questo motivo, sono tentato di provare a leggere questi valori in una matrice 3D numpy e utilizzare Scenario, Anno e Mese come indici. È una cosa sensata da fare?

Credo che avrei potuto anche fare un dizionario, dove le chiavi sono qualcosa come

str(Scenario)+str(Year)+str(Month) 

Questo sarebbe meglio? Ci sono altre opzioni?

(Con "migliore", suppongo che intenda "accesso più rapido", sebbene se un metodo richieda molta meno memoria rispetto a un altro, sarebbe utile saperlo anche in questo caso).

Grazie mille!

+0

Wow - che sito fantastico! 5 persone mi hanno dato grandi risposte in meno tempo di quanto mi ci sia voluto per scrivere la domanda originale. GRAZIE! – JamesS

risposta

8

Vorrei usare un ditt di tuple. Semplice, veloce e una tabella hash per recuperare un singolo valore:

import csv 

reader = csv.reader(open('data.csv', 'rb')) 
header = reader.next() 
data = {} 

for row in reader: 
    key = tuple([int(v) for v in row[:-1]]) 
    val = row[-1] 
    data[key] = float(val) 

# Retrieve a value 
print data[1, 1961, 3] 
+0

Grazie a fmark. Ho copiato e incollato il tuo codice e ha funzionato brillantemente. Non mi aspettavo che qualcuno scrivesse il mio codice per me, ma lo hai fatto comunque :-) – JamesS

+2

È sempre un piacere scrivere una semplice soluzione in python :) – fmark

4

Vorrei utilizzare sqlite3 per archiviare i dati su disco. Sarai in grado di leggere l'intero set di dati o sottoinsiemi attraverso query SQL. È quindi possibile caricare tali dati in una matrice numpy o altra struttura di dati Python, qualunque sia la soluzione più comoda per l'attività.

Se si sceglie di utilizzare sqlite, notare anche che sqlite ha un tipo di dati TIMESTAMP. Potrebbe essere una buona idea combinare anno e mese in un TIMESTAMP. Quando si leggono TIMESTAMP in Python, si può dire allo sqlite3 di convertire automaticamente i TIMESTAMP negli oggetti datetime.datetime, il che ridurrebbe alcuni dei codici di codice che altrimenti avresti dovuto scrivere. Faciliterà inoltre la creazione di query SQL che richiedono tutte le righe tra due date.

+0

Saluti unutbu, questa sembra una buona opzione. Farò un po 'di lettura e vedrò se rientra nelle mie attuali capacità. Nel frattempo userò il suggerimento di fmark dal basso. – JamesS

+0

@JamesS: Nessun problema. Benvenuto in SO! – unutbu

0

Crea un dizionario di dizionari di dizionari come hai descritto. Se hai bisogno di dati come numeri, convertili in numeri una volta quando li leggi e memorizza i numeri nei dict. Sarà più veloce quindi utilizzare le stringhe come chiavi. Fammi sapere se hai bisogno di aiuto con il codice.

2

sqlite è una buona opzione se si accederà ogni volta ai propri valori con parametri diversi.

Se ciò non è il caso, e si accede sempre a questa terzina (scenario, anno, mese), è possibile utilizzare una Tupla (elenco immutabile) come chiave e il valore come valore.

Nel codice sarebbe simile:

d = {} 
d[1, 1961, 12] = 0.5 

o in più codice ciclo generico:

d[scenario, year, month] = value 

in seguito si può semplicemente accedere con:

print d[scenario, year, month] 

Python crea automaticamente la Tupla per te.

Problemi correlati