在 Python 中读取 .mat 文件
Posted
技术标签:
【中文标题】在 Python 中读取 .mat 文件【英文标题】:Read .mat file in Python 【发布时间】:2020-11-03 17:00:59 【问题描述】:我知道如何通过 Python 从附件 (URL) 中调用任何数据,除了与名称“ROI”相关的任何数据。例如,您可以检查“data_dic_save/displacements/roi_ref_formatted”。我想在我的工作中使用来自这条路径的数据(如掩码和区域)。但是,我无法打开(阅读)它们。你能帮帮我吗?
.mat 文件的 URL: https://www.dropbox.com/s/127vo3uew0fppw5/res.mat?dl=0
代码:
with h5py.File('~/res.mat', 'r') as f:
d = f.get('data_dic_save/displacements/roi_ref_formatted')
print(d.attrs['mask'])
错误信息:
KeyError: "Can't open attribute (can't locate attribute: 'mask')"
【问题讨论】:
这是一个有效的问题。您的数据集 (data_dic_save/displacements/roi_ref_formatted
) 没有名为 mask
的属性。这就是你得到错误的原因。可以通过print (d.attrs.__contains__('mask'))
确认,其实这个数据集没有任何属性。
亲爱的kcw78,感谢您的回复。但是,如何从“roi_ref_formatted”读取数据?我在 Matlab 中检查了这个文件,并从这个路径中得到了很多信息。但我需要用 Python 解析这个文件...
您的数据集 (roi_ref_formatted
) 是形状为 (54,1) 的对象引用数组。使用print (d.dtype, d.shape)
进行确认。保存为 HDF5 的 MATLAB 很复杂。它使用指向文件中其他对象的对象引用。要查看它是如何工作的,print (f[ d[0,0] ])
你会得到HDF5 dataset "Lj"
,它是指向f['/#refs#/Lj']
的对象引用你可以通过比较print (f['/#refs#/Lj'][:])
和print (f[ d[0,0] ][:])
来看到这一点
我检查了您的建议并得到以下信息:object (54, 1) displacements
组中的所有数据集都是 54X1 对象引用数组。 strains
组中的所有数据集也是如此。我怀疑dispinfo
和straininfo
组中的数据集提供了映射。我在#refs#
数据集中找到了region
和size_mask
数据。
【参考方案1】:
这个答案是从我上面的 cmets 收集的,以及关于读取保存为 HDF5 的 MATLAB 文件的一些额外见解。坦率地说,它比典型的 HDF5 文件更复杂。
首先,让我们解决您在读取mask
属性时的错误。数据集 data_dic_save/displacements/roi_ref_formatted
没有名为 mask
的属性。这就是你得到错误的原因。您可以通过以下方式确认:
print (d.attrs.__contains__('mask'))
事实上,这个数据集没有任何属性。以下代码将遍历对象d
的所有属性,然后打印属性名称和值:
for name in d.attrs.__iter__():
print (name, h5f.attrs[name])
现在,我们来谈谈 HDF5 格式的 MATLAB 文件。 (警告:我不是 MATLAB 或对象引用方面的专家。我所知道的一切都是通过反复试验学到的)。
我使用 The HDF Group 的 HDFVIEW 打开了您的 .mat 文件。在开始使用 HDF5 时,我认为这是一个必不可少的工具,因为它可以让您在 GUI 中“查看”文件的架构和数据。 (坦率地说,这是我找出 .mat 文件内容的唯一方法。它们不像大多数 HDF5 文件那样具有自我描述性。)本文末尾有您文件的快照供参考。
displacements
组中的所有数据集都是 54X1 对象引用数组。 strains
组中的所有数据集也是如此。我怀疑dispinfo
和straininfo
组中的数据集提供了某种映射。另外,我在#refs#/XX
数据集中发现了region
和size_mask
数据。
您应该阅读 h5py 文档以了解有关对象引用的详细信息。 参考:h5py Object Reference doc
以下是使用您的文件的简要说明。
下面的调用将d
作为形状(54,1)
和dtype object
的NumPy 数组返回。打印语句确认相同。
d = f.get('data_dic_save/displacements/roi_ref_formatted')
print (d.dtype, d.shape)
object (54, 1)
对象引用指向文件中的其他对象。要查看它是如何工作的,请打印d
中的第一个数组条目,您将获得对数据集Lj
的引用(将在组/#refs#
中)。你可以看到Lj
数据集是一个NumPy 数组,形状为(1,6)
,类型为u4
(无符号整数)。
print (f[ d[0,0] ])
<HDF5 dataset "Lj": shape (1, 6), type "<u4">
这意味着以下 2 个语句指向同一个对象并产生相同的结果:
print (f['/#refs#/Lj'][:])
[[3707764736 2 1 1 110 1]]
print (f[ d[0,0] ][:])
[[3707764736 2 1 1 110 1]]
此时,我无法解释您的其余数据。以下是一些可能对您有所帮助的其他答案。
此 SO Q&A 提供了有关读取 .mat 文件的基本说明:read-matlab-v7-3-file-into-python-list-of-numpy-arrays-via-h5py
我写了一个更完整的解释(用于阅读 SVHN 数据集)。您可以在这里访问它:what-is-the-difference-between-the-two-ways-of-accessing-the-hdf5-group-in-svhn
【讨论】:
以上是关于在 Python 中读取 .mat 文件的主要内容,如果未能解决你的问题,请参考以下文章