我有一个pandas HDFStore,我试图从中选择。我想在一个大的np.array中带有id的两个时间戳之间选择数据。以下代码有效但仅在查询列表中的成员资格时占用太多内存。如果我使用datetimeindex和范围,则内存占用量减少95%。
#start_ts, end_ts are timestamps
#instruments is an array of python objects
not_memory_efficient = adj_data.select("US", [Term("date",">=", start_ts),
Term("date", "<=", end_ts),
Term("id", "=", instruments)])
memory_efficient = adj_data.select("US", [Term("date",">=", start_ts),
Term("date", "<=", end_ts),)
在HDFStore中有更多内存有效的方法吗?我应该将索引设置为“sec_id”吗? (我也可以使用chunksize选项并自己连接,但这似乎有点像黑客。)
编辑:
hdfstore由pd.HDFStore创建,创建一个数据帧并存储如此。我之前犯了错误
def write_data(country_data, store_file):
for country in country_data:
if len(country_data[country]) == 0:
continue
df = pd.concat(country_data[country], ignore_index=True)
country_data[country] = []
store_file.append(country, df, format="t")
根据要求,这是此表的ptdump:https://gist.github.com/MichaelWS/7980846 另外,这是df:https://gist.github.com/MichaelWS/7981451
答案 0 :(得分:3)
为其他用户纪念此事。
在HDFStore中,如果某些列不是索引,则需要将某些列指定为data_columns,以便稍后进行查询。
文档为here
创建一个框架
In [23]: df = DataFrame(dict(date = pd.date_range('20130101',periods=10), id = list('abcabcabcd'), C = np.random.randn(10)))
In [28]: df
Out[28]:
C date id
0 0.605701 2013-01-01 00:00:00 a
1 0.451346 2013-01-02 00:00:00 b
2 0.479483 2013-01-03 00:00:00 c
3 -0.012589 2013-01-04 00:00:00 a
4 -0.028552 2013-01-05 00:00:00 b
5 0.737100 2013-01-06 00:00:00 c
6 -1.050292 2013-01-07 00:00:00 a
7 0.137444 2013-01-08 00:00:00 b
8 -0.327491 2013-01-09 00:00:00 c
9 -0.660220 2013-01-10 00:00:00 d
[10 rows x 3 columns]
保存到没有data_columns的hdf
In [24]: df.to_hdf('test.h5','df',mode='w',format='table')
0.13将报告此错误(0.12将默默忽略)
In [25]: pd.read_hdf('test.h5','df',where='date>20130101 & date<20130105 & id=["b","c"]')
ValueError: The passed where expression: date>20130101 & date<20130105 & id=["b","c"]
contains an invalid variable reference
all of the variable refrences must be a reference to
an axis (e.g. 'index' or 'columns'), or a data_column
The currently defined references are: index,columns
将所有列设置为数据列(也可以是特定的列列表)
In [26]: df.to_hdf('test.h5','df',mode='w',format='table',data_columns=True)
In [27]: pd.read_hdf('test.h5','df',where='date>20130101 & date<20130105 & id=["b","c"]')
Out[27]:
C date id
1 0.451346 2013-01-02 00:00:00 b
2 0.479483 2013-01-03 00:00:00 c
[2 rows x 3 columns]
以下是文件的ptdump -av
的表节点:
/df/table (Table(10,)) ''
description := {
"index": Int64Col(shape=(), dflt=0, pos=0),
"C": Float64Col(shape=(), dflt=0.0, pos=1),
"date": Int64Col(shape=(), dflt=0, pos=2),
"id": StringCol(itemsize=1, shape=(), dflt='', pos=3)}
byteorder := 'little'
chunkshape := (2621,)
autoindex := True
colindexes := {
"date": Index(6, medium, shuffle, zlib(1)).is_csi=False,
"index": Index(6, medium, shuffle, zlib(1)).is_csi=False,
"C": Index(6, medium, shuffle, zlib(1)).is_csi=False,
"id": Index(6, medium, shuffle, zlib(1)).is_csi=False}
/df/table._v_attrs (AttributeSet), 19 attributes:
[CLASS := 'TABLE',
C_dtype := 'float64',
C_kind := ['C'],
FIELD_0_FILL := 0,
FIELD_0_NAME := 'index',
FIELD_1_FILL := 0.0,
FIELD_1_NAME := 'C',
FIELD_2_FILL := 0,
FIELD_2_NAME := 'date',
FIELD_3_FILL := '',
FIELD_3_NAME := 'id',
NROWS := 10,
TITLE := '',
VERSION := '2.7',
date_dtype := 'datetime64',
date_kind := ['date'],
id_dtype := 'string8',
id_kind := ['id'],
index_kind := 'integer']
需要注意的关键是data_columns在'description'中是分开的,并且它们被设置为索引。
答案 1 :(得分:2)
您无法提供要通过的大型列表,也不能将整个pandas对象加载到内存中。这是numexpr如何运作的限制。
pandas问题:https://github.com/pydata/pandas/issues/5717
pytables问题:http://sourceforge.net/mailarchive/message.php?msg_id=30390757