2010-01-09 94 views
4

我有兩組文件包含CSV格式的數據與一個公共密鑰(時間戳) - 我需要按時間順序遍歷所有記錄。Python排序文件同步閱讀

  • A組: '環境數據'

    • 文件名是格式A_0001.csv,A_0002.csv等
    • 預排序上升
    • 關鍵是時間戳, ieYYYY-MM-DD HH:MM:SS
    • 包含CSV /列格式的環境數據
    • 非常大數據
  • B組的E,幾個GB值得: '事件數據'

    • 文件名是在格式B_0001.csv,B_0002.csv
    • 預排序升序
    • 鍵是時間戳,即YYYY-MM-DD HH:MM:SS
    • 包含CSV /列格式的基於事件的數據
    • 相對較小升相比,A組的文件,< 100 MB

什麼是最好的辦法?

  • 預合併:使用不同的配方在那裏的一個文件合併成一個單一的有序輸出,然後讀給處理
  • 實時合併:實現代碼爲「合併'的文件實時

我將運行大量的後處理方面的迭代。任何想法或建議?我正在使用Python。

+0

A和B文件編號是否相互對應? – 2010-01-09 23:01:57

+0

每個A文件是否有B文件,反之亦然? (A,B)和i 2010-01-10 03:57:01

+0

有幾百個A組文件,只有幾個B組。每種文件中的數據/記錄隨着時間​​的推移而隨機分佈。然而,A組的記錄數量非常大,因此每個時間戳一般都被覆蓋,但B組記錄的數量小得多,因此記錄被廣泛分散。 – belvoir 2010-01-10 22:21:28

回答

0

我會建議預合併。

讀取文件需要大量的處理器時間。讀兩個文件,兩倍。由於您的程序將處理大量輸入(大量文件,尤其是A組),因此我認爲最好在一個文件讀取中完成它,並將所有相關數據都包含在該文件中。這也會減少您需要的變量和read聲明的數量。

這將提高你的算法的運行時間,並且我認爲這是在這種情況下一個足夠的理由來決定使用這種方法

希望這有助於

2

IM想將它導入到一個數據庫(MySQL的,sqlite等)將會比在腳本中合併更好的性能。數據庫通常有優化的加載csv的例程,並且連接可能會比在python中合併2個字節(一個非常大)的速度更快或更快。

+0

我曾經想過,但我們正在討論數據倉庫級別的記錄。總的來說,我擁有超過100GB的數據(數百萬和數百萬條記錄)。也許我很快就會解僱它,但我認爲使用數據庫進行合併/排序可以在考慮設置文件/記錄的Python中更快速/更優雅地完成。 – belvoir 2010-01-10 22:25:25

0

你可以從你的文件,比如說成批讀,10000條記錄(或任何數量的進一步分析告訴你是最佳的),並在飛行合併。可能使用自定義類來封裝IO;然後可以通過生成器協議訪問實際記錄(__iter__ + next)。

這將是內存友好,很可能在總時間來完成操作方面非常好,能夠使你逐步產生輸出。

草圖:

class Foo(object): 

    def __init__(self, env_filenames=[], event_filenames=[]): 
     # open the files etc. 

    def next(self): 
     if self._cache = []: 
      # take care of reading more records 
     else: 
      # return the first record and pop it from the cache 

    # ... other stuff you need ... 
2

「YYYY-MM-DD HH:MM:SS」 可以用一個簡單的ASCII比較來排序。 如何重用外部合併邏輯?如果第一個字段是密鑰,那麼:

for entry in os.popen("sort -m -t, -k1,1 file1 file2"): 
    process(entry) 
1

這與關係連接類似。由於您的時間戳不必匹配,因此稱爲非Equijoin。

排序合併是幾個流行的算法之一。對於非外源性,它效果很好。我認爲這將是你所謂的「預合併」。我不知道「實時合併」是什麼意思,但我懷疑它仍然是一個簡單的排序合併,這是一種很好的技術,被真正的數據庫大量使用。

嵌套循環也能正常工作。在這種情況下,您可以閱讀外部循環中的較小表格。在內部循環中,您可以查找大表中的所有「匹配」行。這實際上是一種排序合併,但假設大表中會有多行匹配小表。

這,順便說一句,可以讓你更正確地分配的意義,事件數據和環境數據之間的關係。而不是閱讀大量排序合併的結果,並試圖確定您獲得了哪種記錄,嵌套循環處理得很好。

此外,您還可以一邊看大表做「查找」到較小的表。

當你進行不相等的比較時,這是很難的,因爲你沒有一個合適的鍵來從簡單的字典中進行簡單的檢索。然而,你可以很容易地擴展字典(覆蓋__contains____getitem__)在一個鍵上進行範圍比較,而不是簡單的相等性測試。