如何链接使用 Pandas 生成的 HDF5 文件?
Posted
技术标签:
【中文标题】如何链接使用 Pandas 生成的 HDF5 文件?【英文标题】:How to link HDF5 files generated with Pandas? 【发布时间】:2022-01-19 17:02:26 【问题描述】:假设我们有一个文件夹,其中包含pandas.to_hdf
生成的 HDF5 文件。我想创建一个master.h5
文件,其中包含指向所有DataFrames
的外部链接。
根据h5py
的文档,这样做的标准方法是
myfile = h5py.File('master.h5','w')
myfile['ext link'] = h5py.ExternalLink("some_sub_file.h5", "/path/to/resource")
但是pandas.to_hdf
生成的文件不仅包含datasets
,还包含h5py.Groups
。然后,您将如何设置外部链接以正常工作?
【问题讨论】:
【参考方案1】:对 Pandas 和 HDF5 链接的额外研究揭示了一个有趣的发现:链接存在局限性(您可以在 Pandas 中创建它们,但 Pandas 无法访问链接数据)。换句话说,链接就在那里,并且可以与 HDFView、h5py 和 PyTables 一起正常工作。参考这些 GitHub 问题:
Pandas hdf functions should support the hdf5 ExternalLink functionality when reading/writing - Issue #6019 Presence of softlink in HDF5 file breaks HDFStore.keys() - Issue #20523 两者的状态似乎都是打开的。我的测试证实了之前报告的错误。下面的代码显示了如何创建这两种链接类型。它还显示您在尝试访问链接数据时将收到的错误消息。 (错误消息是:KeyError: 'you cannot get attributes from this 'NoAttrs' instance
。这是由于 HDF5 限制属性对链接的限制。HDFStore 节点具有一些必需的属性。当 Pandas 尝试读取属性时,结果是“NoAttrs”消息。
import pandas as pd
df1 = pd.DataFrame( "a": [1,2,3,4], "b": [11,12,13,14] )
print(df1.to_string())
# Create file 1 with simple dataframe
f1 = "test_1.hdf"
with pd.HDFStore(f1, mode="w") as hdf1:
hdf1.put("/key1", df1)
# Create file 2 with external link
f2 = "test_extlink.hdf"
with pd.HDFStore(f2, mode="w") as hdf2:
hdf2._handle.create_external_link(hdf2._handle.root, "extlink_key1", f"f1:/key1")
print("Successful external link write")
with pd.HDFStore(f2, mode="r") as hdf2:
print(hdf2.keys()) # Notice that [] (no keys) is printed
# following lines will trigger the 'NoAttrs' error message
# df2test = pd.read_hdf(f2,key="extlink_key1")
# print(df2test.to_string())
print("End external link read")
# Create file 3 with simple dataframe and symbolic (soft) link
f3 = "test_symlink.hdf"
with pd.HDFStore(f3, mode="w") as hdf3:
hdf3.put("/key1", df1)
hdf3._handle.create_soft_link(hdf3._handle.root, "symlink_key1", "/key1")
print("Successful symbolic link write")
with pd.HDFStore(f3, mode="r") as hdf3:
print(hdf3.keys()) # Notice that only ['key1'] is printed
# following lines will trigger the 'NoAttrs' error message
# df3test = pd.read_hdf(f3,key="symlink_key1")
# print(df3test.to_string())
print("End symbolic link read")
【讨论】:
【参考方案2】:链接可以指向 HDF5 数据结构(数据集或组)中的任何对象。文件是组的一种特殊形式;称为根组并用'/'
引用。因此,要链接到文件,请使用:h5py.ExternalLink(filename,'/')
。
您没有说是否需要每个文件中的每个数据框/数据集的链接,或者每个文件的链接。创建指向文件根组的链接更简单。如果您为数据集创建单独的链接,请确保指定唯一名称。
每种方法都有 2 个答案。这些问题并不是专门针对h5py.ExternalLink()
,但我对每个问题的回答都使用了外部链接。请参阅以下答案:
我修改了第二个答案 (70089964) 中的代码,以显示如何在 3 个文件中创建从主文件到根组的 3 个外部链接(其中每个文件有 5 个数据集)。
创建 3 个示例文件的代码:
import h5py
import numpy as np
for fcnt in range(3):
fname = f'file_fcnt+1.h5'
with h5py.File(fname,'w') as h5fw:
for dscnt in range(1,6,1):
arr = np.random.random(10).reshape(5,2)
h5fw.create_dataset(f'data_fcnt*10+dscnt:02',data=arr*dscnt)
创建从主文件到 3 个文件的链接的代码:
import h5py
fnames = ['file_1.h5','file_2.h5','file_3.h5']
with h5py.File(f'master_len(fnames)_links.h5','w') as h5fw:
for fname in fnames:
with h5py.File(fname,'r') as h5fr:
h5fw[fname] = h5py.ExternalLink(fname,'/')
【讨论】:
以上是关于如何链接使用 Pandas 生成的 HDF5 文件?的主要内容,如果未能解决你的问题,请参考以下文章