【问题标题】:Selecting columns from pandas.HDFStore table从 pandas.HDFStore 表中选择列
【发布时间】:2012-12-05 06:04:22
【问题描述】:

如何从 pandas HDFStore 中检索特定列?我经常处理非常大的数据集,这些数据集太大而无法在内存中进行操作。我想迭代地读取一个 csv 文件,将每个块附加到 HDFStore 对象中,然后处理数据的子集。我已经阅读了一个简单的 csv 文件并将其加载到 HDFStore 中,代码如下:

tmp = pd.HDFStore('test.h5')
chunker = pd.read_csv('cars.csv', iterator=True, chunksize=10, names=['make','model','drop'])
tmp.append('df', pd.concat([chunk for chunk in chunker], ignore_index=True))

还有输出:

In [97]: tmp
Out[97]:
<class 'pandas.io.pytables.HDFStore'>
File path: test.h5
/df     frame_table (typ->appendable,nrows->1930,indexers->[index])

我的问题是如何从tmp['df'] 访问特定列?该文档提到了 select() 方法和一些 Term 对象。提供的示例适用于面板数据;但是,我太新手了,无法将其扩展到更简单的数据框案例。我的猜测是我必须以某种方式创建列的索引。谢谢!

【问题讨论】:

    标签: python pandas hdfs


    【解决方案1】:

    HDFStore 记录表的方式,列按类型存储为单个 numpy 数组。你总是会取回所有的列,你可以过滤它们,所以你会根据你的要求返回。在 0.10.0 中,您可以传递包含列的 Term。

    store.select('df', [ Term('index', '>', Timestamp('20010105')), 
                         Term('columns', '=', ['A','B']) ])
    

    或者你可以在之后重新索引

    df = store.select('df', [ Term('index', '>', Timestamp('20010105') ])
    df.reindex(columns = ['A','B'])
    

    axes 并不是真正的解决方案(您实际创建的实际上是存储转置帧)。此参数允许您重新排序轴的存储,以以不同方式启用数据对齐。对于数据框来说,它真的没有多大意义。对于 3d 或 4d 结构,磁盘数据对齐对于真正快速的查询至关重要。

    0.10.1 将允许一个更优雅的解决方案,即数据列,即您可以选择某些列来表示为表存储中有自己的列,因此您真的可以只选择它们。这是即将到来的味道。

     store.append('df', columns = ['A','B','C'])
     store.select('df', [ 'A > 0', Term('index', '>', Timestamp(2000105)) ])
    

    解决此问题的另一种方法是将单独的表存储在文件的不同节点中,然后您可以只选择您需要的。

    总的来说,我再次推荐非常宽的桌子。 hayden 提供了 Panel 解决方案,这可能对您现在有好处,因为实际的数据排列应该反映您希望如何查询数据。

    【讨论】:

    • 0.10.1有这个功能吗?我一直无法使用它。 github 上的未解决问题是什么?
    • 0.10.1 支持数据列;你有什么问题?
    • 我认为我们应该更新它以避免混淆,杰夫?
    【解决方案2】:

    您可以使用列的索引来存储数据框,如下所示:

    import pandas as pd
    import numpy as np
    from pandas.io.pytables import Term
    
    index = pd.date_range('1/1/2000', periods=8)
    df = pd.DataFrame( np.random.randn(8,3), index=index, columns=list('ABC'))  
    
    store = pd.HDFStore('mydata.h5')
    store.append('df_cols', df, axes='columns')
    

    然后根据需要选择:

    In [8]: store.select('df_cols', [Term('columns', '=', 'A')])
    Out[8]: 
    2000-01-01    0.347644
    2000-01-02    0.477167
    2000-01-03    1.419741
    2000-01-04    0.641400
    2000-01-05   -1.313405
    2000-01-06   -0.137357
    2000-01-07   -1.208429
    2000-01-08   -0.539854
    

    地点:

    In [9]: df
    Out[9]: 
                       A         B         C
    2000-01-01  0.347644  0.895084 -1.457772
    2000-01-02  0.477167  0.464013 -1.974695
    2000-01-03  1.419741  0.470735 -0.309796
    2000-01-04  0.641400  0.838864 -0.112582
    2000-01-05 -1.313405 -0.678250 -0.306318
    2000-01-06 -0.137357 -0.723145  0.982987
    2000-01-07 -1.208429 -0.672240  1.331291
    2000-01-08 -0.539854 -0.184864 -1.056217
    

    .

    对我来说,这不是一个理想的解决方案,因为我们只能通过一件事来索引 DataFrame!令人担忧的the docs 似乎建议您可以只用一件事索引 DataFrame,至少使用axes

    将轴关键字与维度列表一起传递(当前必须比对象的总维度小 1)。

    我可能读错了,在这种情况下希望有人能证明我错了!

    .

    注意:我发现通过两件事(索引和列)对 DataFrame 进行索引的一种方法是将其转换为 Panel,然后可以使用两个索引进行检索。但是,每次检索项目时,我们都必须将所选子面板转换为 DataFrame ......再次,不理想。

    【讨论】:

    • 索引应该是日期时间吗?我使用字符作为索引,并以与您相同的方式进行。但是,当我在您的代码中(在 [8] 中)使用 select 语句时。它检索了整个数据框。我在这里错过了什么吗??
    • 见下面我的回答;你基本上是在存储一个转置的帧。此处不需要轴参数
    • 这个例子中的大多数东西都对我有用,除了这一行:store.append('df_cols', df, axes='columns') 它会引发错误ValueError: No axis named c for object type &lt;class 'pandas.core.frame.DataFrame'&gt; 如果你将该行替换为:store.append('df_cols', df, data_columns=True),那么错误就会消失,其余的示例有效。
    • @karenyng 正如 Jeff 所说,不需要轴参数。我认为自从发布此答案以来,它实际上已被弃用(并被删除)......:谢谢!
    【解决方案3】:

    从现在开始,你可以使用查询表达式代替Term 构造。 例如:store.select('df', "index &gt; Timestamp('20000105')")

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-28
      • 1970-01-01
      • 2022-09-28
      • 2018-02-17
      • 1970-01-01
      • 1970-01-01
      • 2020-02-10
      相关资源
      最近更新 更多