【问题标题】:pandas read_hdf with large set of conditions具有大量条件的 pandas read_hdf
【发布时间】:2016-10-27 22:25:26
【问题描述】:

我尝试使用 pandas 库读取 64 GB(用 blosc 压缩)的 HDF 文件。 Dataframe 包含 3 列和 11410996915 行。我正在尝试使用 pandas.read_hdf 方法和 where 参数按索引选择具体行。问题是有时我需要获取数千行,所以在我的 where 参数中我放了这样的内容:

simMat = pd.read_hdf('global.h5','matrix', columns=['similarity'], where='index in {}'.format(listIdx))

其中 listIdx 是表示我想要返回的索引的整数列表。当此列表包含超过 31 个元素时,我会收到内存错误。我开始查看 pandas 库的代码,发现在文件 pytables.py 中的 BinOp 类中有一个名为 _max_selectors 的变量,其赋值为 31。该变量在这段代码之后使用:

# if too many values to create the expression, use a filter instead
if self.op in ['==', '!='] and len(values) > self._max_selectors:

    filter_op = self.generate_filter_op()
    self.filter = (
       self.lhs,
       filter_op,
       pd.Index([v.value for v in values]))
    return self

过滤器的使用会导致库尝试加载整个数据帧,这会引发 MemoryError。我也尝试使用值为 10 的 chunksize 参数,但它也不起作用。你知道用这么大的索引集查询 HDF 文件的更好方法吗?

【问题讨论】:

    标签: python pandas dataframe pytables


    【解决方案1】:

    您可以使用以下技术:

    pd.read_hdf(filename, 'key', where='index = vals')
    

    其中valspd.SeriesPython list 变量

    您也可以使用属于其他 DF 的列进行过滤:

    In [201]: another_df = pd.DataFrame(np.random.randint(0, 100, size=(100, 3)), columns=list('abc'))
    
    In [202]: pd.read_hdf(fn, 'test', where='a = another_df["a"]').shape
    Out[202]: (573, 3)
    

    或其他 DF 的索引:

    In [203]: pd.read_hdf(fn, 'test', where='index = another_df.index').shape
    Out[203]: (100, 3)
    

    演示:

    设置

    fn = r'D:\temp\.data\hdf\test.h5'
    
    store = pd.HDFStore(fn)
    
    df = pd.DataFrame(np.random.randint(0, 10**4, size=(10**5, 3)), columns=list('abc'))
    
    store.append('test', df, data_columns=True, complib='blosc', complevel=5)
    
    store.close()
    

    测试

    vals = pd.Series(np.random.randint(0, 100, 500))
    
    In [196]: pd.read_hdf(fn, 'test', where='index = vals').shape
    Out[196]: (98, 3)
    

    与 Python 列表相同:

    idx_list = vals.tolist()
    
    In [197]: pd.read_hdf(fn, 'test', where='index = idx_list').shape
    Out[197]: (98, 3)
    

    【讨论】:

      猜你喜欢
      • 2015-04-29
      • 2019-01-20
      • 2023-03-14
      • 2022-01-23
      • 2018-10-20
      • 2021-04-06
      • 1970-01-01
      • 1970-01-01
      • 2012-12-21
      相关资源
      最近更新 更多