HDFStore获取列名称

时间:2018-03-21 08:34:09

标签: python pandas dataframe hdfstore

我有一些问题,大熊猫'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是一个每列有一个函数的dictonary。这也非常慢。
  5. 为了绘图,我必须读入整个数据框,然后获取列:hdfstore.get('/name').columns
  6. 问题

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

    类似的问题

    How to access single columns using .select 我看到我可以使用它来仅检索某些列,但只有在我知道列名称之后,我认为。

    感谢您的任何建议!

3 个答案:

答案 0 :(得分:1)

对于HDF商店hdfkey(来自hdf.keys()),您可以获取列名:

# 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也可以正常工作,但它会将所有数据读入内存,而上述方法只会读取列名。

完整的工作示例:

#!/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.')

答案 1 :(得分:0)

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

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格式:

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. 如果您需要附加/删除/查询数据-必须使用table格式。如果您只需要写一次即可读很多书-fixed将提高性能。
  3. 至于日期时间索引,我认为在这里我们可以使用与1子句相同的想法。如果您能够将所有数据转换为单一类型,则可以提高性能。
  4. 对您的问题发表评论的其他建议都没想到。

答案 2 :(得分:0)

  1. 不读取任何数据的列:
store.get_storer('df').ncols # substitute 'df' with your key
# you can also access nrows and other useful fields
  1. 从文档(fixed formattable format):((粗体中的重要点)

[已固定]这些类型的存储区一旦写入,就不能不可追加(尽管您可以简单地将其删除并重写)。 它们也不可查询;必须完整检索它们。它们还不支持具有非唯一列名的数据框。固定格式存储区的写入速度比表存储区快,读取速度也稍快。

[]从概念上讲,表的形状非常类似于具有行和列的DataFrame。在相同或其他会话中,表可以附加。另外,支持删除和查询类型操作

  1. 您可以尝试使用历元(或历元)(自历元以来的毫秒或纳秒)代替日期时间。这样,您就可以处理整数索引。

  2. 如果您需要对大型数据进行分组,则可以看看this answer


建议:如果您有4个问题要问,最好对SO提出4个单独的问题。这样,您将获得更多(更高质量)的答案,因为每个答案都更易于解决。每个人都会处理一个特定的主题,从而使寻找特定答案的人更加容易。