我在一个HDFStore
中有约700万行数据,包含60多列。这些数据太多,我无法将其全部载入内存。我想根据一列"A"的值对数据进行分组聚合。Pandas的文档(拆分/聚合/组合)假设我已经将所有数据都读入了DataFrame
中,但是我无法将整个存储库读入内存中的DataFrame
中。在HDFStore
中分组数据的正确方法是什么?
我在一个HDFStore
中有约700万行数据,包含60多列。这些数据太多,我无法将其全部载入内存。我想根据一列"A"的值对数据进行分组聚合。Pandas的文档(拆分/聚合/组合)假设我已经将所有数据都读入了DataFrame
中,但是我无法将整个存储库读入内存中的DataFrame
中。在HDFStore
中分组数据的正确方法是什么?
这里是一个完整的例子。
import numpy as np
import pandas as pd
import os
fname = 'groupby.h5'
# create a frame
df = pd.DataFrame({'A': ['foo', 'foo', 'foo', 'foo',
'bar', 'bar', 'bar', 'bar',
'foo', 'foo', 'foo'],
'B': ['one', 'one', 'one', 'two',
'one', 'one', 'one', 'two',
'two', 'two', 'one'],
'C': ['dull', 'dull', 'shiny', 'dull',
'dull', 'shiny', 'shiny', 'dull',
'shiny', 'shiny', 'shiny'],
'D': np.random.randn(11),
'E': np.random.randn(11),
'F': np.random.randn(11)})
# create the store and append, using data_columns where I possibily
# could aggregate
with pd.get_store(fname) as store:
store.append('df',df,data_columns=['A','B','C'])
print "store:\n%s" % store
print "\ndf:\n%s" % store['df']
# get the groups
groups = store.select_column('df','A').unique()
print "\ngroups:%s" % groups
# iterate over the groups and apply my operations
l = []
for g in groups:
grp = store.select('df',where = [ 'A=%s' % g ])
# this is a regular frame, aggregate however you would like
l.append(grp[['D','E','F']].sum())
print "\nresult:\n%s" % pd.concat(l, keys = groups)
os.remove(fname)
输出
store:
<class 'pandas.io.pytables.HDFStore'>
File path: groupby.h5
/df frame_table (typ->appendable,nrows->11,ncols->6,indexers->[index],dc->[A,B,C])
df:
A B C D E F
0 foo one dull -0.815212 -1.195488 -1.346980
1 foo one dull -1.111686 -1.814385 -0.974327
2 foo one shiny -1.069152 -1.926265 0.360318
3 foo two dull -0.472180 0.698369 -1.007010
4 bar one dull 1.329867 0.709621 1.877898
5 bar one shiny -0.962906 0.489594 -0.663068
6 bar one shiny -0.657922 -0.377705 0.065790
7 bar two dull -0.172245 1.694245 1.374189
8 foo two shiny -0.780877 -2.334895 -2.747404
9 foo two shiny -0.257413 0.577804 -0.159316
10 foo one shiny 0.737597 1.979373 -0.236070
groups:Index([bar, foo], dtype=object)
result:
bar D -0.463206
E 2.515754
F 2.654810
foo D -3.768923
E -4.015488
F -6.110789
dtype: float64
一些警告:
1)如果您的组密度相对较低,例如数百或数千个组,则此方法是有意义的。如果超过这个数量,则有更高效(但更复杂的)方法,并且应用您正在应用的函数(在本例中为 sum
)会变得更加限制。
基本上,您将通过块迭代整个存储库,一边分组一边进行,但仅将组保留为半折叠状态(想象一下做平均值,因此您需要在结束时保持运行总数和运行计数,然后进行除法)。因此,某些操作可能会更加棘手,但可能处理许多组(而且速度非常快)。
2)可以通过保存坐标(例如,组位置,但这会更加复杂)来提高其效率。
3)不适用于多重分组(虽然是可能的,但需要像上面提到的2)一样的方法)
4)您想要分组的列必须是数据列!
5)您可以在选择中组合任何其他筛选器(顺便说一下,这是进行多重分组的一种聪明方式,您只需形成两个唯一的组列表并迭代它们的乘积,如果您有许多组,则不是非常高效,但可以工作)
希望对您有所帮助
如果此方法对您有用,请告诉我
groups = store.unique('df','A')
应更改为 groups = store.select_column('df', 'A').unique()
。 - IanHstore.select_column('df','A').unique()
会触发完整读取,如果df['A']
太大而无法放入内存怎么办? - agemO