Python(pandas):用多重索引将数据框存储为hdf5
我需要处理一个大尺寸的数据框,并且这个数据框有多个索引,所以我尝试创建一个数据框来学习如何把它存储在hdf5文件里。
这个数据框长这样:(前两列是多个索引)
Symbol Date 0
C 2014-07-21 4792
B 2014-07-21 4492
A 2014-07-21 5681
B 2014-07-21 8310
A 2014-07-21 1197
C 2014-07-21 4722
2014-07-21 7695
2014-07-21 1774
我在使用pandas.to_hdf,但它创建了一个“固定格式存储”,当我尝试从一个组中选择数据时:
store.select('table','Symbol == "A"')
它返回了一些错误,主要的问题是这个
TypeError: cannot pass a where specification when reading from a Fixed format store. this store must be selected in its entirety
然后我尝试像这样追加数据框:
store.append('ts1',timedata)
这应该会创建一个表格,但却给了我另一个错误:
TypeError: [unicode] is not implemented as a table column
所以我需要一些代码来把数据框以表格的形式存储在hdf5格式中,并且能够从单个索引中选择数据(为此我找到了这段代码:store.select('timedata','Symbol == "A"')
)
2 个回答
1
Jeff的回答完全正确。我发现了一些小问题,想分享一下,这些内容不适合放在评论里,所以请把这当作一个长一点的补充评论 :)
(Pytables版本) 如果你在尝试写入hdf文件时遇到缺少属性或方法的错误,建议你更新一下PyTables的版本。Pandas(截至目前)是依赖于Pytables的,我发现至少有一对版本组合会出现一些奇怪的错误,直到我更新了Pytables并重新加载。
(数据类型) 这个问题在Python 3中可能已经解决,但在2.7x版本中,to_hdf在处理unicode、混合数据类型的列和浮点数中的NaN值时会有问题。下面是一个示例工具函数,用于清理DataFrame,以便准备写入to_hdf,这个函数解决了我遇到的所有问题。请注意,这个函数将NaN替换为零,这对我的应用来说是合适的,但你可能需要根据自己的情况进行调整:
def clean_cols_for_hdf(data):
types = data.apply(lambda x: pd.lib.infer_dtype(x.values))
for col in types[types=='mixed'].index:
data[col] = .data[col].astype(str)
data[<your appropriate columns here>].fillna(0,inplace=True)
return data
这些内容也扩展了Jeff的一些评论。Jeff真是太棒了,请原谅我添加的这个答案,但我想补充一些对我有帮助的细节。
6
这里有一个例子
In [8]: pd.__version__
Out[8]: '0.14.1'
In [9]: np.__version__
Out[9]: '1.8.1'
In [10]: import sys
In [11]: sys.version
Out[11]: '2.7.3 (default, Jan 7 2013, 09:17:50) \n[GCC 4.4.5]'
In [4]: df = DataFrame(np.arange(9).reshape(9,-1),index=pd.MultiIndex.from_product([list('abc'),date_range('20140721',periods=3)],names=['symbol','date']),columns=['value'])
In [5]: df
Out[5]:
value
symbol date
a 2014-07-21 0
2014-07-22 1
2014-07-23 2
b 2014-07-21 3
2014-07-22 4
2014-07-23 5
c 2014-07-21 6
2014-07-22 7
2014-07-23 8
In [6]: df.to_hdf('test.h5','df',mode='w',format='table')
In [7]: pd.read_hdf('test.h5','df',where='date=20140722')
Out[7]:
value
symbol date
a 2014-07-22 1
b 2014-07-22 4
c 2014-07-22 7
In [12]: pd.read_hdf('test.h5','df',where='symbol="a"')
Out[12]:
value
symbol date
a 2014-07-21 0
2014-07-22 1
2014-07-23 2