2014-01-24 24 views
2

我在HDFStore中有一個非常大的表,我想用查詢選擇一個子集,然後通過塊遍歷子集塊。我希望之前的查詢發生在之前,選擇被分解爲塊,以便所有塊都具有相同的大小。使用HDFStore查詢對選擇進行迭代

文檔here似乎表明這是默認行爲,但不是很清楚。然而,在我看來,該分塊實際發生查詢之前,如本例所示:

In [1]: pd.__version__ 
Out[1]: '0.13.0-299-gc9013b8' 

In [2]: df = pd.DataFrame({'number': np.arange(1,11)}) 

In [3]: df 
Out[3]: 
    number 
0  1 
1  2 
2  3 
3  4 
4  5 
5  6 
6  7 
7  8 
8  9 
9  10 

[10 rows x 1 columns] 


In [4]: with pd.get_store('test.h5') as store: 
      store.append('df', df, data_columns=['number']) 

In [5]: evens = [2, 4, 6, 8, 10] 

In [6]: with pd.get_store('test.h5') as store: 
      for chunk in store.select('df', 'number=evens', chunksize=5): 
       print len(chunk) 

     2 
     3 

我希望只有大小5的單個塊,如果查詢了結果之前發生的事情被分割成塊,但這個例子給出了兩個長度爲2和3的塊。

這是預期的行爲,如果有的話,是否有一個有效的解決方法來給出相同大小的塊而不將表讀入內存?

回答

4

我想我寫這個時,意圖是使用chunksize查詢的結果。我認爲它在實施過程中發生了變化。塊大小決定查詢應用的部分,然後對這些部分進行迭代。問題是你不知道你會得到多少行。

然而,他們是一種方式來做到這一點。這是草圖。使用select_as_coordinates來實際執行您的查詢;這將返回行號(座標)的Int64Index。然後將迭代器應用到您根據這些行選擇的位置。

像這樣的東西(這使得一個好用的祕方,將包括文檔我認爲):

In [15]: def chunks(l, n): 
     return [l[i:i+n] for i in xrange(0, len(l), n)] 
    ....: 

In [16]: with pd.get_store('test.h5') as store: 
    ....:  coordinates = store.select_as_coordinates('df','number=evens') 
    ....:  for c in chunks(coordinates, 2): 
    ....:   print store.select('df',where=c) 
    ....:   

    number 
1  2 
3  4 

[2 rows x 1 columns] 


    number 
5  6 
7  8 

[2 rows x 1 columns] 


    number 
9  10 

[1 rows x 1 columns] 
在開發文檔
+0

現在:http://pandas.pydata.org/pandas-docs/dev/ io.html#迭代器 – Jeff