2010-11-12 12 views
9

Jestem nowy w Pythonie i mam prawdopodobnie bardzo podstawowe pytanie o "najlepszy" sposób przechowywania danych w moim kodzie. Każda rada bardzo doceniona!Najbardziej odpowiednia struktura danych (Python)

mam długi plik .csv w następującym formacie:

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

Mój scenariusz Wartości uruchomić od 1 do 100, rok idzie od 1961 do 1990 roku, a miesiąc przechodzi od 1 do 12. Mój plik ma zatem 100 * 29 * 12 = 34800 wierszy, z których każdy ma przypisaną wartość.

Chciałbym przeczytać ten plik w jakiejś strukturze danych Pythona, aby uzyskać dostęp do "Wartości", określając "Scenariusz", "Rok" i "Miesiąc". Jak najlepiej to zrobić (lub jakie są różne opcje)?

W mojej głowie myślę o tych danych jako o "sześciennej liczbie" z osiami dla Scenariusza, Roku i Miesiąca, tak aby każda Wartość znajdowała się we współrzędnych (Scenariusz, Rok, Miesiąc). Z tego powodu, mam pokusę, aby spróbować odczytać te wartości w tablicy 3D numpy i użyć Scenariusza, Roku i Miesiąca jako indeksów. Czy to rozsądne?

Chyba mogę również zrobić słownika gdzie klawisze są coś

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

Czy to będzie lepiej? Czy są inne opcje?

(Przez "lepsze" przypuszczam, że mam na myśli "szybszy dostęp", chociaż jeśli jedna metoda jest znacznie mniej intensywna od pamięci, dobrze byłoby o tym wiedzieć).

Dziękuję bardzo!

+0

Wow - co za fantastyczna strona! 5 osób udzieliło mi wspaniałych odpowiedzi w krótszym czasie, niż zajęło mi napisanie oryginalnego pytania. DZIĘKUJĘ CI! – JamesS

Odpowiedz

8

Użyłbym dyktatu krotek. Prosty, szybki i lookh-look, aby pobrać jedną wartość:

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

Dzięki fmark. Skopiowałem i wkleiłem twój kod i wszystko działało znakomicie. Nie spodziewałem się, że ktoś napisze dla mnie kod, ale i tak to zrobiłeś :-) – JamesS

+2

Zawsze jest miło napisać proste rozwiązanie w pythonie :) – fmark

4

Chciałbym użyć sqlite3 do przechowywania danych na dysku. Będziesz mógł czytać w pełnym zbiorze danych lub podzbiorach za pomocą zapytań SQL. Następnie możesz załadować te dane do tablicy numpy lub innej struktury danych Pythona - co jest najwygodniejsze dla tego zadania.

Jeśli zdecydujesz się użyć sqlite, zwróć także uwagę, że sqlite ma typ danych TIMESTAMP. Dobrym pomysłem może być łączenie roku i miesiąca w jeden TIMESTAMP. Po przeczytaniu TIMESTAMPów w Pythonie, można powiedzieć, że sqlite3 automatycznie konwertuje TIMESTAMPy na obiekty datetime.datetime, co zmniejszyłoby część kodu standardowego, który musiałbyś napisać. Ułatwi to również tworzenie zapytań SQL, które wymagają wszystkich wierszy między dwiema datami.

+0

Pozdrawiam unutbu, to brzmi jak dobra opcja. Zrobię trochę czytania i zobaczę, czy to w moich obecnych możliwościach. W międzyczasie wykorzystam sugestię fmark z dołu. – JamesS

+0

@ James: Nie ma problemu. Witamy w SO! – unutbu

0

Stwórz słownik słowników takich, jak opisałeś. Jeśli potrzebujesz danych jako liczb, zamień je na liczby raz, gdy je przeczytasz i zapisze numery w dyktach. Będzie to szybsze niż użycie łańcuchów jako kluczy. Daj mi znać, jeśli potrzebujesz pomocy z kodem.

2

sqlite to fajna opcja, jeśli za każdym razem uzyskujesz dostęp do wartości za pomocą różnych parametrów.

Jeśli tak nie jest i zawsze będziesz mieć dostęp do tego trypletu (scenariusz, rok, miesiąc), możesz użyć Krotki (niezmiennej listy) jako klucza i wartości jako wartości.

W kodzie to będzie wyglądać:

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

lub w bardziej ogólny kod pętli:

d[scenario, year, month] = value 

później można po prostu do niego dostęp z:

print d[scenario, year, month] 

Python automatycznie twórz Tuple dla ciebie.

Powiązane problemy