2012-12-18 74 views
15

如何從熊貓HDFStore中檢索特定列?我經常使用非常大的數據集,這些數據集太大而無法在內存中操作。我想迭代讀取一個csv文件,將每個塊附加到HDFStore對象中,然後處理數據的子集。我看過一個簡單的CSV文件,用下面的代碼加載它變成一個HDFStore:從pandas.HDFStore表中選擇列

tmp = pd.HDFStore('test.h5') 
chunker = pd.read_csv('cars.csv', iterator=True, chunksize=10, names=['make','model','drop']) 
tmp.append('df', pd.concat([chunk for chunk in chunker], ignore_index=True)) 

和輸出:

In [97]: tmp 
Out[97]: 
<class 'pandas.io.pytables.HDFStore'> 
File path: test.h5 
/df  frame_table (typ->appendable,nrows->1930,indexers->[index]) 

我的問題是我如何訪問來自tmp['df']特定的列?該文檔提到了一個select()方法和一些Term對象。所提供的例子適用於Panel數據;然而,我太過於將它擴展到更簡單的數據框的情況。我的猜測是我必須以某種方式創建列的索引。謝謝!

回答

11

HDFStore記錄表格的方式是將列按類型存儲爲單個numpy數組。你總是找回所有的列,你可以過濾它們,所以你會回來爲你的要求。在0.10.0中,您可以傳遞涉及列的Term。

store.select('df', [ Term('index', '>', Timestamp('20010105')), 
        Term('columns', '=', ['A','B']) ]) 

,或者你可以重新索引之後

df = store.select('df', [ Term('index', '>', Timestamp('20010105') ]) 
df.reindex(columns = ['A','B']) 

axes是不是真的在這裏解決方案(你實際上創造了什麼是效果存儲換位幀)。該參數允許您重新排列軸的存儲,以不同的方式啓用數據對齊。對於數據幀來說,它並不意味着太多。對於3d或4d結構,磁盤上的數據對齊對真正快速的查詢至關重要。

0.10。1將允許更優雅的解決方案,即數據列,也就是說,您可以選擇某些列作爲表格存儲中的自己的列來表示,因此您只能選擇它們。這是一種嘗試即將到來的。

store.append('df', columns = ['A','B','C']) 
store.select('df', [ 'A > 0', Term('index', '>', Timestamp(2000105)) ]) 

另一種方法是將單獨的表存儲在文件的不同節點中,然後您只能選擇所需的內容。

一般來說,我推薦再寬真正的桌子。海頓提供了面板解決方案,這對您而言可能會有所幫助,因爲實際的數據安排應反映您想要如何查詢數據。

+0

0.10.1中的這個特性是否存在?我一直無法使用它。 github上的開放問題是什麼? – alexbw

+0

0.10.1支持數據列;你有什麼問題? – Jeff

+0

我想我們應該更新這個以避免混淆,傑夫? –

11

您可以將數據幀存儲與列的指標如下:

import pandas as pd 
import numpy as np 
from pandas.io.pytables import Term 

index = pd.date_range('1/1/2000', periods=8) 
df = pd.DataFrame(np.random.randn(8,3), index=index, columns=list('ABC')) 

store = pd.HDFStore('mydata.h5') 
store.append('df_cols', df, axes='columns') 

,然後選擇你可能希望:

In [8]: store.select('df_cols', [Term('columns', '=', 'A')]) 
Out[8]: 
2000-01-01 0.347644 
2000-01-02 0.477167 
2000-01-03 1.419741 
2000-01-04 0.641400 
2000-01-05 -1.313405 
2000-01-06 -0.137357 
2000-01-07 -1.208429 
2000-01-08 -0.539854 

其中:

In [9]: df 
Out[9]: 
        A   B   C 
2000-01-01 0.347644 0.895084 -1.457772 
2000-01-02 0.477167 0.464013 -1.974695 
2000-01-03 1.419741 0.470735 -0.309796 
2000-01-04 0.641400 0.838864 -0.112582 
2000-01-05 -1.313405 -0.678250 -0.306318 
2000-01-06 -0.137357 -0.723145 0.982987 
2000-01-07 -1.208429 -0.672240 1.331291 
2000-01-08 -0.539854 -0.184864 -1.056217 

對我來說,這不是一個理想的解決方案,因爲我們只能通過一件事物索引DataFrame!令人擔憂的是the docs似乎表明您可以只指數一件事數據幀,至少使用axes

Pass the axes keyword with a list of dimension (currently must by exactly 1 less than the total dimensions of the object).

我可能不正確地讀這篇文章,在這種情況下希望有人能證明我錯了!

注意:我發現通過兩種方式(索引和列)來索引DataFrame的一種方法是將其轉換爲Panel,然後使用兩個索引進行檢索。然而,每次檢索項目時,我們都必須將所選子面板轉換爲DataFrame ...再次,並不理想。

+0

該指數應該是日期時間嗎?我用字符作爲索引,並按照你所做的相同的方式進行。但是,當我通過代碼中的select語句來到時(在[8]中)。它檢索了整個數據幀。我在這裏錯過了什麼? – JustInTime

+0

請參閱下面的答案;你基本上是存儲一個轉置幀。這裏不需要軸參數 – Jeff

+3

本例中的大多數東西都適用於我,除了這一行: 'store.append('df_cols',df,axes ='columns')' 它引發錯誤 'ValueError:No如果您將該行替換爲: 'store.append('df_cols',df,data_columns = True)' 那麼錯誤就會出現在對象類型' '並且其餘的例子工作。 – karenyng