4

我想每天从一个巨大的 hdf5 中选择一个数据子集。使用where 掩码是完美的,但我不能让它与 multiindex 一起工作(因为我必须有一个 where 有两个条件)。不能使用带有多索引的 where 掩码:

import itertools
import pandas as pd
import numpy as np
a = ('A', 'B')
i = (0, 1, 2)
idx = pd.MultiIndex.from_tuples(list(itertools.product(a, i)),
                            names=('Alpha', 'Int'))
df = pd.DataFrame(np.random.randn(len(idx), 7), index=idx,
              columns=('I', 'II', 'III', 'IV', 'V', 'VI', 'VII'))

在此处输入图像描述

好的,现在我把它放在一个 hdf 商店

from pandas.io.pytables import HDFStore
store =HDFStore('cancella.h5', 'w')
store.append('df_mask',df)

但如果我再读一遍,我有

c = store.select_column('df_mask','index')
print c

这个索引是错误的。

0    0
1    1
2    2
3    3
4    4
5    5
dtype: int64

所以我不能使用where 掩码。你能帮助我吗?

4

4 回答 4

0

我猜这是因为 pandas 可能reset_index在将表放入之前HDF5(原因可能是它试图避免任何潜在的重复索引,这在数据帧中是允许的,但对数据库非常不利),并使用整数自动递增的主键作为索引HDF5桌子。因此,您在帖子中编写的代码选择了这些自动递增的主键。

可能还有其他一些更优雅的方法,但我发现了以下工作。(如果确实是 pandas 的结果reset_index,所以现在多级索引变成列......)

import itertools
import pandas as pd
import numpy as np
a = ('A', 'B')
i = (0, 1, 2)
idx = pd.MultiIndex.from_tuples(list(itertools.product(a, i)),
                            names=('Alpha', 'Int'))
df = pd.DataFrame(np.random.randn(len(idx), 7), index=idx,
              columns=('I', 'II', 'III', 'IV', 'V', 'VI', 'VII'))
print(df)

store = pd.HDFStore('/home/Jian/Downloads/temp.h5')
store.append('df_mask',df)

store.select('df_mask', columns=['Alpha','Int'])

在此处输入图像描述

于 2015-07-11T14:25:42.627 回答
0

您是否尝试过使用 Pandas to_hdf(安装 pytables 之后)?

df.to_hdf('/Users/Alexander/Downloads/hdf.h5', key='data', format='t')

>>> pd.read_hdf('/Users/Alexander/Downloads/hdf.h5', 'data', columns='index')
Empty DataFrame
Columns: []
Index: [(A, 0), (A, 1), (A, 2), (B, 0), (B, 1), (B, 2)]

选择 format='t' 选项:

“写为 PyTables 表结构,它可能性能更差,但允许更灵活的操作,如搜索/选择数据子集”

本文档提供了使用where掩码选择数据的详细信息。

于 2015-07-11T16:25:39.323 回答
0

这可能与您的问题正交,但我没有在您的 DataFrame 中看到名为“索引”的列或索引,所以我不知道您实际选择的是什么

c = store.select_column('df_mask','index')

我一直使用read_hdf包装器来处理 PyTables,并且发现它非常灵活。它的语法非常灵活,例如

c = pd.read_hdf('/home/Jian/Downloads/temp.h5', 'df_mask', where="Alpha='A' | Alpha='B' & Int=0")

您的 where 子句中的条件数量有严格限制,但如果我正确阅读了您的问题,那对您来说将是第二个问题。

于 2015-07-23T22:04:55.533 回答
0

在当前的 pandas 版本 0.24.2 中,您可以使用直接查询而无需中间 MultiIndex 检索:

idx = pd.MultiIndex.from_product([('A', 'B'), range(3)], names=('Alpha', 'Int'))
df = pd.DataFrame(np.random.randn(len(idx), 3), index=idx,
                  columns=('I', 'II', 'III'))
df

>>>                    I           II         III
>>> Alpha   Int             
>>>     A   0    0.547846   -1.630704    0.456686
>>>         1   -0.057442   -0.232721    0.349548
>>>         2    1.495230    0.661166    1.309862
>>>     B   0    2.116818    0.477923   -0.252352
>>>         1    1.001081    2.578723   -0.040782
>>>         2   -1.286964    0.357969    0.002976

只需使用内置where掩码:

with pd.HDFStore('test.h5') as store:
    store.put('df_mask', df, format='t')
    store.select('df_mask', where = 'Alpha = A & Int in [0,2]')

>>>                         I          II        III
>>> Alpha   Int             
>>>     A     0      0.621453   -1.757883   0.494433
>>>           2     -0.689012   -1.254884   0.655424

对于掩码访问文档中允许的不同功能。

但是,如果您想要的过滤器非常复杂,并且您想要检索 MultiIndex 并“手动”构建掩码,您可以像这样选择它:

with pd.HDFStore('test.h5') as store:
    store.select('df_mask', columns=['index'])

>>> Alpha   Int
>>>     A     0
>>>           1
>>>           2
>>>     B     0
>>>           1
>>>           2
于 2019-06-01T01:07:14.537 回答