繁体   English   中英

从HDF5文件读取pandas.Dataframe列的子集

[英]Reading a subset of the columns of the pandas.Dataframe from a HDF5 file

我将pandas.DataFrame保存在HDF5文件中。 DataFrame由多个列组成,并且尺寸很大。 HDF5文件中每个表的大小均大于2GB。 为了进行分析,希望仅将表的列的子集加载到内存中。

使用SQLite3,这是一件微不足道的工作。 可以使用“从table1中选择column1,colum2,...”进行查询。 有没有在Python中执行此操作的简单方法?

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

同样,对于应用程序,希望以pandas.DataFrame的形式读取数据。 稍后将在不同的列中产生数据。 如果数据保存在DataFrame中,则用户不必在产生新数据时进行解码。 如果可能的话,犯错的机会会减少。

我该如何解决这个问题?

我不知道仅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'])

Nakor的解决方案Nowruri从数据帧中提取一个切片(作为matrix )。 他使用切片创建(并返回)一个新的数据框。 可以修改他的解决方案以返回numpy检索(使用pandas列名称作为字段名称)。

这是我对def partial_load()修改,以使用h5py创建并返回一个h5py 只要matrix是单个数据类型,这就是有效的。 如果它具有多个类型,则需要进行修改才能正确创建recarray dtype。

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]

    dt_list = []
    for col_name in col_subset:
        dt_list.append((col_name, matrix.dtype),)
    matrix_recarr = np.recarray((matrix.shape[0],),dtype=np.dtype(dt_list))
    for col in range(len(col_subset)):
        matrix_recarr[col_subset[col]] = matrix[:,col]

    return matrix_recarr

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM