使用dd.read_hdf读取自定义HDF5文件时遇TypeError错误求助
问题:Dask read_hdf无法读取h5py保存的HDF5文件?
问题详情
我希望使用dd.read_hdf()方法,通过Dask DataFrame加载Pandas DataFrame。创建基础Pandas DataFrame后,将其数值、列名和索引拆分,用h5py保存为HDF5文件,自定义的加载函数能正常还原原DataFrame,但调用dd.read_hdf(my_path, key="values")时出现如下错误:
TypeError: An error occurred while calling the read_hdf method registered to the pandas backend. Original Message: cannot create a storer if the object is not existing nor a value are passed
用pd.HDFStore查看该文件时显示store为空,想知道操作哪里有误,是否遗漏了基础步骤?
复现代码
import pandas as pd import numpy as np import dask.dataframe as dd import h5py def save_hdf5(df, hdf5_path): # Separate the DataFrame values, column names, and index values = df.values columns = df.columns.to_numpy() index = df.index.to_numpy() # Save to HDF5 file with different groups with h5py.File(hdf5_path, 'w') as hdf: hdf.create_dataset('values', data=values) hdf.create_dataset('columns', data=columns) hdf.create_dataset('index', data=index) def load_hdf5(hdf5_path): # Load the data from the HDF5 file with h5py.File(hdf5_path, 'r') as hdf: values = hdf['values'][:] # Load entire dataset into memory columns = hdf['columns'][:].astype(str) # Load and convert back to strings index = hdf['index'][:].astype(str) # Load and convert back to strings return pd.DataFrame(values, columns=columns, index=index) # Create a simple pandas DataFrame data = {'A': [1, 2, 3], 'B': [4, 5, 6]} df = pd.DataFrame(data) df.index =['one','two','three'] # File path for the HDF5 file my_path = 'my_df.h5' save_hdf5(df, my_path) my_df = load_hdf5(my_path)
原因与解决方法
核心原因
你用h5py直接保存的HDF5文件不是Pandas/HDFStore的标准格式:
- Pandas的
to_hdf()会在HDF5文件中写入特定的元数据结构(包括storer对象、索引和列的结构化信息),供pd.read_hdf和dd.read_hdf识别。 - 而h5py只是将数据作为普通HDF5数据集存储,没有这些Pandas专属的元数据,所以
pd.HDFStore会显示为空,Dask依赖Pandas的HDF读取逻辑自然无法解析。
解决方法
方法1:使用Pandas原生to_hdf保存(推荐)
直接用Pandas自带的to_hdf方法保存DataFrame,生成的文件完全兼容Dask的read_hdf:
# 替换原save_hdf5函数的保存逻辑 df.to_hdf(my_path, key='df', mode='w') # 用Dask读取 ddf = dd.read_hdf(my_path, key='df')
方法2:自定义Dask读取逻辑(特殊场景)
如果必须用h5py拆分存储,需要手动构建Dask DataFrame,步骤如下:
- 读取元数据(列名、索引)
- 用
dask.array.from_array延迟加载数值数据 - 转换为Dask DataFrame并设置列名和索引
示例代码:
import dask.array as da import dask.dataframe as dd def load_dask_hdf5(hdf5_path): with h5py.File(hdf5_path, 'r') as hdf: # 获取元数据 columns = hdf['columns'][:].astype(str) index = hdf['index'][:].astype(str) # 延迟加载数值数组,按需设置chunks大小 values_da = da.from_array(hdf['values'], chunks=(1, 2)) # 转换为Dask DataFrame ddf = dd.from_dask_array(values_da, columns=columns) # 设置索引(注意:Dask索引建议有序,字符串索引需按需处理) ddf = ddf.set_index(da.from_array(index)) return ddf # 使用示例 ddf = load_dask_hdf5(my_path)
内容的提问来源于stack exchange,提问作者Aenaon
相关产品推荐
相关产品推荐

