如何将含可变长度数组的Pandas DataFrame保存为可复用格式(如HDF5)并支持Matlab读取?
如何将含可变长度数组的Pandas DataFrame保存为可复用格式(如HDF5)并支持Matlab读取?
我太懂你这个痛点了——当DataFrame里混着可变长度的数组列时,直接用df.to_hdf(format='fixed')要么报错,要么存出来的文件Matlab根本读不懂。毕竟fixed格式要求每列数据类型和长度都得统一,完全hold不住你列a里那种长短不一的数组。我给你两个亲测有效的方案,兼顾Pandas复用和Matlab读取:
方案一:用h5py手动构建HDF5文件(优先推荐,Matlab读取最顺畅)
直接绕开Pandas的to_hdf限制,用h5py手动控制存储结构,这样存出来的文件Matlab能直接识别,没有兼容性问题。
先上完整代码:
import h5py import numpy as np import pandas as pd # 你的原始数据 data = { 'a': [np.array([1.,2.]), np.array([6.,7.,.6]), np.array([np.nan])], 'b': np.array([99., 66., 88.]) } df = pd.DataFrame(data) # 构建兼容Matlab的HDF5文件 with h5py.File('df_matlab_friendly.h5', 'w') as f: # 存储列b:普通一维数组直接存就行 f.create_dataset('b', data=df['b'], dtype='float64') # 存储列a:定义HDF5可变长度数据类型(对应float64数组) var_len_float = h5py.special_dtype(vlen=np.dtype('float64')) # 创建对应数据集,形状是行数,类型是可变长度数组 dset_a = f.create_dataset('a', shape=(len(df['a']),), dtype=var_len_float) # 逐个写入每个可变长度数组 for idx, arr in enumerate(df['a']): dset_a[idx] = arr
为什么这个方案好用?
- 存出来的HDF5文件,Matlab用
h5read就能直接读,而且列a会自动变成Matlab的cell数组,完美对应原来的可变长度数据:b = h5read('df_matlab_friendly.h5', '/b'); a = h5read('df_matlab_friendly.h5', '/a'); - 不管你的数组是2个元素、3个元素还是单元素带NaN,都能正确存储和读取,没有数据丢失。
方案二:用Pandas的table格式存储(适合需要保留Pandas结构的场景)
如果你还是想保留Pandas的DataFrame结构,方便后续用Pandas直接读取,可以把format='fixed'换成format='table':
df.to_hdf('df_pandas_table.h5', mode='w', key='data', format='table')
注意事项
- Pandas用
pd.read_hdf('df_pandas_table.h5', key='data')就能直接读回原DataFrame,完全没问题。 - 但Matlab读取的时候,得找对数据集的路径:列
b在/data/table/b,列a在/data/table/a。不过Matlab读取这个列a时,需要稍微处理一下,因为Pandas的table格式会把object列存成嵌套结构,不如方案一直接。所以如果优先照顾Matlab的使用体验,还是方案一更靠谱。
最后再提两个小提醒:
- 永远别用
format='fixed'存带可变长度数组的DataFrame,它会因为数据类型不统一直接报错,或者偷偷给你把数据存坏。 - 如果你数组里有NaN,不用额外处理,h5py和Pandas的table格式都能正确存储,Matlab读取后也能识别为
NaN。
内容来源于stack exchange
相关产品推荐
相关产品推荐

