首页 > 解决方案 > 从 HDF5 文件中读取 pandas.Dataframe 列的子集

问题描述

我将 pandas.DataFrame 保存在 HDF5 文件中。DataFrame 由多列组成,大小非常大。HDF5 文件中每个表的大小>2GB。对于分析,希望仅将表的列的子集加载到内存中。

使用 SQLite3 这是一项微不足道的工作。可以使用“select column1, colum2, ... from table1”进行查询。在 Python 中有没有一种简单的方法可以做到这一点?

请注意, pandas.read_hdf 不是一个好的解决方案。此函数将整个表加载到内存中,然后删除未使用 'columns= .. ' 参数指定的列。所以一开始难免会有非常大的内存占用。

此外,对于应用程序,需要以 pandas.DataFrame 的形式读取数据。稍后将使用不同的列生成数据。如果数据保存在 DataFrame 中,则用户无需在生成新数据时进行解码。如果可能,犯错的机会就会变小。

我该如何解决这个问题?

标签: pythonpandasnumpyhdf5h5py

解决方案


我不知道pandas唯一的解决方案,但你可以h5py直接通过图书馆。也许这可以工作?

import h5py
import pandas as pd
import numpy as np

def decode(array):
    return [x.decode() for x in array]

def partial_load(filename,key,col_subset):
    handle = h5py.File(filename,'r')
    columns = decode(handle.get("{}/axis0".format(key))[:])
    rows = decode(handle.get("{}/axis1".format(key))[:])

    col_subset_idx = np.isin(columns,col_subset)
    matrix = handle.get("{}/block0_values".format(key))[:,col_subset_idx]

    df = pd.DataFrame(matrix, columns=col_subset, index=rows)
    return df

# Fake data
nrow,ncol = (100,5000)
rd_df = pd.DataFrame(np.random.randint(0,10,[nrow,ncol]),
                     index=["row{}".format(i) for i in range(nrow)],
                     columns=["col{}".format(i) for i in range(ncol)])
rd_df.to_hdf('test.h5','abc')

# Load subset
matrix_subset = partial_load('test.h5','abc',['col1','col5'])

推荐阅读