我在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的块。
这是预期的行为,如果有的话,是否有一个有效的解决方法来提供相同大小的块而不将表读入内存?
答案 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]