2011-04-17 48 views
4

我還是很新的使用python來從頭開始編程,所以作爲一個練習,雖然我會拿一個文件來處理使用SQL,嘗試使用Python來複制功能。看來我想把我的(壓縮的,zip)csv文件並創建一個Dict(或者可能是一個字典詞典?)。當我使用dict閱讀器時,我將第一行作爲關鍵字,而不是每一列作爲自己的關鍵字?例如。帶有所有列名的CSV到Python字典?

import csv, sys, zipfile 
sys.argv[0] = "/home/tom/Documents/REdata/AllListing1RES.zip" 
zip_file = zipfile.ZipFile(sys.argv[0]) 
items_file = zip_file.open('AllListing1RES.txt', 'rU') 

for row in csv.DictReader(items_file,dialect='excel'): 
    pass 

產量:

>>> for key in row: 
     print 'key=%s, value=%s' % (key, row[key]) 

key=MLS_ACCT PARCEL_ID AREA COUNTY STREET_NUM STREET_NAME CITY  ZIP STATUS PROP_TYPE LIST_PRICE LIST_DATE DOM DATE_MODIFIED BATHS_HALF BATHS_FULL BEDROOMS ACREAGE YEAR_BUILT YEAR_BUILT_DESC OWNER_NAME SOLD_DATE WITHDRAWN_DATE STATUS_DATE SUBDIVISION PENDING_DATE SOLD_PRICE, 
value=492859 28-15-3-009-001.0000 200 JEFF 3828 ORLEANS RD MOUNTAIN BROOK 35243 A SFR 324900 3/3/2011 2 3/4/2011 12:04:11 AM 0 2 3 0 1968 EXIST SPARKS   3/3/2011 11:54:56 PM KNOLLWOOD 

所以,我正在尋找的是爲MLS_ACCT列和一個單獨的一個PARCEL_ID等這樣我就可以再由包含KNOLLWOOD所有項目做這樣的事情的平均價格在SUBDIVISION字段有日期範圍的另一個小節,銷售日期等。

我很清楚如何用SQL來完成它,但正如我所說的,我正在爭取在這裏獲得一些Python技能。 過去幾天我一直在閱讀,但在這類用例中還沒有找到任何非常簡單的插圖。指向所述文檔將不勝感激。我意識到我可以使用內存駐留的SQL-lite,但我的願望是再次學習Python方法。我在Numpy和Scipy上閱讀了一些內容,並且加載了聖人,但仍然無法找到一些有用的插圖,因爲這些工具似乎集中在只有數字作爲元素的數組,我有很多字符串匹配,我需要做以及日期範圍計算和比較。

最後我需要替換表中的值(因爲我有髒數據),我現在通過一個「翻譯表」來做到這一點,該翻譯表包含所有髒變量併爲最終使用提供「乾淨」的答案。

+0

我們需要更多有關您正在構建的詞典結構的更多信息以給出更確切的答案...讓我們假設您將所有這些數據填入名爲'mls'的詞典中...您想如何訂購關鍵字段?城市,細分,地址等等?此外,我懷疑,在你與循環詞典鍵循環一段時間後,'sqllite'內存將更具吸引力... – 2011-04-17 18:30:26

+0

Dan提供了基本答案這些標籤讓我大吃一驚,你提到的更廣泛的問題是現在是我的問題,正如我最初所說的,我擁有所有在SQL中工作的S **,但是我將它用作Python的學習案例。總之,我需要大部分基本組和總和/平均值(以及使用表上的替代數據創建視圖,以提供清理「髒」數據等等,以便脫離SQL但嘗試理解在Python中使用最好的結構和方法來獲得類似的結果,數據集大約有500,000行 – dartdog 2011-04-17 19:03:11

回答

6

您確定這是一個包含逗號分隔值的文件嗎?看起來這些行由製表符分隔。

如果這是正確的,請在DictReader構造函數中指定製表符分隔符。

for row in csv.DictReader(items_file, dialect='excel', delimiter='\t'): 
    for key in row: 
     print 'key=%s, value=%s' % (key, row[key]) 

來源:http://docs.python.org/library/csv.html

+0

嗯,我認爲這可能是類似的東西...所以現在我有數據..現在談到更廣泛的問題是正確的方式去解決這個問題? – dartdog 2011-04-17 18:42:20

0

乍一看這似乎是你的輸入可能不會實際上是CSV,但也許是標籤,而不是分隔。查看python.org的文檔,您可以創建一個Dialect並使用它來更改分隔符。

import csv 
csv.register_dialect('exceltab', delimiter='\t') 
for row in csv.DictReader(items_file,dialect='exceltab'): 
    pass 
+0

感謝您的快速反應!丹擊敗你,雖然! – dartdog 2011-04-17 18:56:02

1

用純Python編寫操作當然是可以的,但是你必須選擇你的算法。上面發佈的行輸出看起來很像解析錯誤;事實上,它似乎不是一個CSV,它是一個TSV?嘗試將delimiter='\t'dialect=csv.excel_tab傳遞給DictReader。

一旦閱讀完成正確,DictReader應該可以將行作爲字典,這是一種典型的面向行的結構。奇怪的是,這通常不是處理像你這樣的查詢的有效方式;只有列列表使搜索更容易。行方向意味着你必須爲每一行重做一些查找工作。諸如日期匹配之類的事情要求數據肯定不存在於CSV中,例如日期如何表示以及哪些列是日期。

得到一個面向列的數據結構(但是,涉及加載整個文件)的一個例子:

import csv 
allrows=list(csv.reader(open('test.csv'))) 
# Extract the first row as keys for a columns dictionary 
columns=dict([(x[0],x[1:]) for x in zip(*allrows)]) 

的要列出並在變量存儲的中間步驟是不必要的。關鍵是使用zip(或其堂兄itertools.izip)轉置表。

然後用某一標準中所有行one列提取柱two

matchingrows=[rownum for (rownum,value) in enumerate(columns['one']) if value>2] 
print map(columns['two'].__getitem__, matchingrows) 

當你知道一個列的類型,它可能是有意義的分析它,使用適當的功能,如datetime.datetime.strptime

+0

謝謝你的迴應,,我有數據現在使用選項卡規格..數據是約500,000行,我想嘗試做所有在內存中查詢,你可以詳細說明一下,或者指向我一些更多的資源,我想我應該至少將數據轉換爲適當的Python類型,特別是日期時間和美元到十進制..我'我真的不在尋找喲你寫d **的東西!但仍然需要更多的指針! – dartdog 2011-04-17 18:55:03

+0

我真的不確定你在這裏有什麼指導。它看起來像你在用SQL思考;來自一種編程語言的非常普遍的效果,但是SQL甚至不是一種通用的編程語言。它是針對特定結構的數據庫的查詢語言,因此有了這樣的問題,您只需使用Python構建RDBMS。我們確實有很多可以使用的函數,比如sum和decimal類型,但是Python的核心是一個連續的命令式語言 - 一個非常不同的野獸。列表理解,地圖等是從函數式編程繼承而來的。看看這些。 – 2011-04-18 19:47:48