2010-11-12 120 views
9

我是Python的新手,有什麼可能是關於在我的代碼中存儲數據的「最佳」方式的一個非常基本的問題。任何建議非常感謝!最合適的數據結構(Python)

我有以下格式的長.csv文件:

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

我的方案值從1跑到100,一年過得1961年至1990年和月月都有從1到12,因此,我的文件有100 * 29 * 12 = 34800行,每行都有相關的值。

我想將此文件讀入某種Python數據結構,以便通過指定'場景','年份'和'月'來訪問'值'。請這樣做的最佳方式是什麼(或有哪些選擇)?

在我的腦海中,我認爲這些數據是一種'數字長方體',包含場景,年份和月份的座標軸,以便每個值都位於座標(場景,年份,月份)中。出於這個原因,我很想嘗試將這些值讀入3D numpy數組,並使用Scenario,Year和Month作爲索引。這是明智的做法嗎?

我想我也可以做一本字典,其中鍵是像

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

這將是更好?還有其他選擇嗎?我認爲我的意思是'訪問速度更快',但如果一種方法比另一種方法的內存密集程度低得多,那麼也應該知道這一點。)。

非常感謝!

+0

哇 - 多麼美妙的網站! 5人在比我寫出原始問題更少的時間內給了我很好的答案。謝謝! – JamesS 2010-11-12 12:39:15

回答

8

我會使用元組的字典。簡單,快速,哈希表查找檢索單個值:

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

謝謝fmark。我複製並粘貼了您的代碼,並且效果非常出色。我沒有期待任何人爲我寫代碼,但無論如何你都這樣做了:-) – JamesS 2010-11-12 12:41:54

+2

它總是很高興在python中編寫一個簡單的解決方案:) – fmark 2010-11-12 12:43:11

4

我會使用sqlite3將數據存儲到磁盤。您將能夠通過SQL查詢讀入完整的數據集或子集。然後,您可以將該數據加載到一個numpy數組或其他Python數據結構中 - 無論對於任務來說最方便。

如果你選擇使用sqlite,還要注意sqlite有一個TIMESTAMP數據類型。 將年份和月份合併爲一個TIMESTAMP可能是一個好主意。當你讀入Python的TIMESTAMP時,可以告訴sqlite3自動將TIMESTAMPs轉換爲datetime.datetime對象,這樣會減少一些你必須編寫的樣板代碼。它還將使得更容易地形成SQL查詢來請求兩個日期之間的所有行。

+0

乾杯unutbu,這聽起來像一個很好的選擇。我會做一些閱讀,看看它是否在我目前的能力範圍內。與此同時,我將從下面使用fmark的建議。 – JamesS 2010-11-12 12:43:29

+0

@JamesS:沒問題。歡迎來到SO! – unutbu 2010-11-12 12:59:07

0

製作一本你所描述的字典字典。如果您需要數據作爲數字,當您讀取它們並將數字存儲在字典中時,將它們轉換爲數字一次。使用字符串作爲關鍵字會更快。讓我知道是否需要幫助代碼。

2

如果你打算每次訪問不同的參數你的值,sqlite是一個不錯的選擇。

如果情況並非如此,並且您將始終以此三元組(場景,年,月)訪問,則可以使用Tuple(不可變列表)作爲您的鍵,並將該值作爲您的值。

在代碼它看起來像:

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

或更通用的循環代碼:

d[scenario, year, month] = value 

以後你可以只是訪問:

print d[scenario, year, month] 

Python會自動爲你創建Tuple。