2013-12-16 90 views
11

我正在使用具有數百萬行和100列以上的Oracle數據庫。我試圖用索引某些列的pytables將這些數據存儲在HDF5文件中。我將在pandas DataFrame中讀取這些數據的子集並執行計算。從Oracle讀取數百萬行的大表並寫入HDF5

我已經嘗試以下操作:

下載的表格,使用工具到CSV文件中,通過使用塊讀取大熊貓CSV文件塊,並使用pandas.HDFStore追加到HDF5表。我創建了一個dtype定義並提供了最大字符串大小。

但是,現在當我試圖直接從Oracle DB下載數據並通過pandas.HDFStore將其發佈到HDF5文件時,我遇到了一些問題。

pandas.io.sql.read_frame不支持分塊讀取。我沒有足夠的RAM能夠將整個數據首先下載到內存中。

如果我嘗試使用帶有固定數量記錄的cursor.fecthmany(),則在數據庫表中讀取操作需要很長時間纔會編制索引,並且我必須讀取日期範圍內的記錄。我正在使用DataFrame(cursor.fetchmany(), columns = ['a','b','c'], dtype=my_dtype) 然而,創建的DataFrame總是推斷dtype而不是強制執行我提供的dtype(與read_csv不同,它遵守我提供的dtype)。因此,當我將此數據幀附加到已存在的HDFDatastore時,會出現類型不匹配的情況。 float64可能會在一個塊中被解釋爲int64。

欣賞如果你們可以提供你的想法並指向正確的方向。

+7

你目前的做法(帶有csv)和dtype校正是正確的。 SQL將在0.14(0.13即將發佈)中獲得重大更新。所以不幸的是dtype infererence/chunking不可用。歡迎PRS的!看到這個問題:https://github.com/pydata/pandas/issues/4163 – Jeff

+2

我建議刪除Oracle標記,除非你在Oracle方面有任何問題。 –

+1

你應該讓你的dba將錶轉換爲範圍分區對象,之後應該很容易通過分區訪問 – klashxx

回答

0

好了,所以我沒有與Oracle數據庫太多的經驗,但這裏的一些想法:

由於缺少索引以及您希望按照時間戳順序存儲數據,您從Oracle訪問任何特定記錄的時間很慢。

首先,你不能啓用數據庫的索引?

如果您無法操作數據庫,那麼您可能會請求一個僅包含每行的已排序唯一標識的發現集?

您可能會將這些數據存儲爲唯一ID的單個數組,您應該可以將其放入內存中。如果每個唯一密鑰允許4k(保守估計,包括開銷等),並且不保留時間戳,所以它只是一個整數數組,它可能會爲300萬條記錄耗用大約1.1GB的RAM。這不是一個完整的堆,大概你只想要一個活動數據的小窗口,或者你正在逐行處理?

做一個生成器函數來完成所有這些。這樣,一旦完成迭代,它應該釋放內存,而不必刪除任何內容,並且它還使代碼更容易遵循,並避免膨脹計算循環的實際重要邏輯。

如果你不能將它全部存儲在內存中,或者出於其他原因,這是行不通的,那麼你可以做的最好的事情就是計算出你可以在內存中存儲多少內存。您可以將作業分成多個請求,並在最後一個完成後使用多線程發送請求,同時將數據處理到新文件中。它不應該耗盡內存,直到您要求返回數據。如果延遲是請求正在實現,或者正在下載數據,請嘗試並研究。

從它的聲音中,你可能會抽象數據庫,並讓大熊貓發出請求。可能值得看看它是如何限制結果的。您應該能夠對所有數據發出請求,但只能從數據庫服務器一次加載一行結果。

相關問題