通过查询HDFStore迭代选择

时间:2014-01-24 21:01:24

标签: python-2.7 pandas

我在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的块。

这是预期的行为,如果有的话,是否有一个有效的解决方法来提供相同大小的块而不将表读入内存?

1 个答案:

答案 0 :(得分:4)

我想当我写这篇文章时,意图是使用查询结果的 chunksize 。我认为它在实施时已经改变了。 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]