首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >HDFStore获取列名

HDFStore获取列名
EN

Stack Overflow用户
提问于 2018-03-21 08:34:09
回答 3查看 2.7K关注 0票数 2

我有一些问题,熊猫的HDFStore太慢,不幸的是,我无法从其他问题中找到一个令人满意的解决方案。

情况

我有一个很大的DataFrame,主要包含浮点数,有时还包含整数列,这些列需要经过多个处理步骤(重命名,删除坏条目,聚合30分钟)。每一行都有一个与其关联的时间戳。我想将一些中间步骤保存到HDF文件中,这样用户就可以迭代地执行一个步骤,而不必每次从头开始。

此外,用户应该能够从这些保存中绘制某些列,以便选择坏数据。因此,我只想检索列名,而不读取HDFStore中的数据。具体来说,用户应该获得存储在HDF中的所有数据文件的所有列的列表,然后他们应该选择他们想要看到的列,然后我使用matplotlib来显示相应的数据。

数据

shape == (5730000, 339)看起来一点也不大,这就是为什么我感到困惑.(随着时间的推移,可能会有更多的行,列应该保持不变),在第一步中,我迭代地追加行和列(运行良好),但一旦完成,我总是一次处理整个DataFrame,只对数据进行分组或删除。

我的方法

  1. 我做内存中的所有操作,因为熊猫似乎速度相当快,I/O速度更慢(我认为HDF在不同的物理服务器上)
  2. 我使用日期时间索引,并自动选择浮动或整数列。
  3. 我使用hdf.put('/name', df, format='fixed')保存步骤,因为hdf.put('/name'.format(grp), df, format='table', data_columns=True)似乎太慢了。
  4. 我使用例如df.groupby(df.index).first()df.groupby(pd.Grouper(freq='30Min')).agg(agg_dict)来处理数据,其中agg_dict是一个二叉树,每个列都有一个函数。这也太慢了。
  5. 要进行绘图,我必须读取整个数据帧,然后获取列:hdfstore.get('/name').columns

问题

  • 如何在不读取HDFStore数据的情况下检索所有列?
  • 存储我的数据最有效的方法是什么?HDF是正确的选择吗?桌子还是固定的?
  • 如果索引是日期时间索引,那么效率是否重要?是否存在一种更有效的格式(例如,所有列都相同,固定的dtype?)
  • 是否有更快的方法代替groupby (df.groupby(pd.Grouper(freq='30Min')).agg(agg_dict))进行聚合?

类似问题

.select我看到,我可以使用它只检索特定的列,但只有在我知道列名之后,我想。

谢谢你的建议!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-03-23 15:46:37

对于HDFStore hdfkey (来自hdf.keys()),可以使用以下方法获取列名:

代码语言:javascript
复制
# Table stored with hdf.put(..., format='table')
columns = hdf.get_node('{}/table'.format(key)).description._v_names

# Table stored with hdf.put(..., format='fixed')
columns = list(hdf.get_node('{}/axis0'.format(key)).read().astype(str))

注意,hdf.get(key).columns也能工作,但它将所有数据读入内存,而上面的方法只读取列名。

完整的工作示例:

代码语言:javascript
复制
#!/usr/bin/env python
import pandas as pd

data = pd.DataFrame({'a': [1,1,1,2,3,4,5], 'b': [2,3,4,1,3,2,1]})

with pd.HDFStore(path='store.h5', mode='a') as hdf:
    hdf.put('/DATA/fixed_store', data, format='fixed')
    hdf.put('/DATA/table_store', data, format='table', data_columns=True)
    for key in hdf.keys():
        try:
            # column names of table store
            print(hdf.get_node('{}/table'.format(key)).description._v_names)
        except AttributeError:
            try:
                # column names of fixed store
                print(list(hdf.get_node('{}/axis0'.format(key)).read().astype(str)))
            except AttributeError:
                # e.g. a dataset created by h5py instead of pandas.
                print('unknown node in HDF.')
票数 2
EN

Stack Overflow用户

发布于 2019-06-01 01:22:59

您可以简单地通过指定相同的DataFrame和stop属性来加载0行的start。并保留大熊猫的所有内部索引/列处理:

代码语言:javascript
复制
idx = pd.MultiIndex.from_product([('A', 'B'), range(2)], 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.472412    0.436486    0.354592
>>>           1     -0.095776   -0.598585   -0.847514
>>>     B     0      0.107897    1.236039   -0.196927
>>>           1     -0.154014    0.821511    0.092220

以下两种方法都适用于fixedtable格式:

代码语言:javascript
复制
with pd.HDFStore('test.h5') as store:
    store.put('df', df, format='f')
    meta = store.select('df', start=1, stop=1)
    meta
    meta.index
    meta.columns

>>>               I     II    III
>>> Alpha   Int             
>>>
>>> MultiIndex(levels=[[], []],
>>>            codes=[[], []],
>>>            names=['Alpha', 'Int'])
>>>
>>> Index(['I', 'II', 'III'], dtype='object')

至于其他人的问题:

  1. 只要您的数据基本上是同构的(正如您提到的那样,几乎浮动列),并且您可以将其存储在单个文件中,而不需要跨计算机分发数据-- HDF是第一件尝试的事情。
  2. 如果需要追加/delete/query数据,则必须使用table格式。如果你只需要写一次和读很多- fixed会提高性能。
  3. 至于日期时间索引,我认为这里我们可以使用与1子句相同的想法。如果你能够将所有的数据转换成单一的类型,那么它将提高你的性能。
  4. 在对你的问题的评论中,没有想到任何其他的建议。
票数 3
EN

Stack Overflow用户

发布于 2020-07-30 10:11:57

  1. 不读取任何数据的列:
代码语言:javascript
复制
store.get_storer('df').ncols # substitute 'df' with your key
# you can also access nrows and other useful fields
  1. 来自文档(固定格式表格格式):(粗体中的要点)

固定的--这些类型的存储是,而不是可附加的(尽管您可以简单地删除和重写它们)。也不是可查询的;必须完整地检索它们。它们也不支持具有非唯一列名的数据格式。固定格式存储比表存储提供非常快的写入和稍快的读取速度。从概念上说,表的形状非常类似于DataFrame,包含行和列。表可以在同一会话或其他会话中追加。此外,还支持删除和查询类型操作

  1. 您可以尝试使用历元(或历元)(毫秒或自历元起的纳秒)来代替日期时间。这样,您只需要处理整数索引。
  2. 如果您需要对大型数据进行分组,您可能需要查看这个答案

建议:如果你有4个问题要问,最好是问4个单独的问题。这样,您将获得更多(更高质量)的答案,因为每个答案都更容易处理。每个人都会处理一个特定的话题,这样就可以更容易地找到那些寻找特定答案的人。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49401464

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档