【问题标题】:Python: Issue reading in str from MATLAB .mat file using h5py and NumPyPython:使用 h5py 和 NumPy 从 MATLAB .mat 文件中读取 str 问题
【发布时间】:2019-07-06 17:24:56
【问题描述】:

我很难将 MATLAB .mat 文件中的“str”变量“Et”(结束时间)和“St”(开始时间)加载到 Python 中。

我想要与 MATLAB 中相同的输出。相反,我在尝试解决这个问题时遇到了问题。有关 Python 代码和输出,请参见下文。

# Import numpy and h5py to load in .mat files
import numpy as np
import h5py 

# Load in Matlab ('-v7.3') data
fname = 'directory/file.mat'
f = h5py.File(fname,'r') 

# create dictionary for data
data= {"average":np.array(f.get('average')),"median":np.array(f.get('median')), \
             "stdev":np.array(f.get('stdev')),"P10":np.array(f.get('p10')), \
             "P90":np.array(f.get('p90')),"St":np.str(f.get('stime')), \
             "Et":np.str(f.get('etime'))}
# All other variables are arrays

print(data["Et"])

输出:

<HDF5 dataset "etime": shape (1, 6), type "<u4">

我希望 python 中的字符串等于 MATLAB 中的字符串。 换句话说,我想要 print(data["Et"]) = '01011212000000' 这是日期和时间。

我该如何解决这个问题?

MATLAB 中的数据示例:

【问题讨论】:

  • 至少对于 Octave 'hdf5' 文件,f['average'] 有 2 个数据集,'type' 和 'value'。分开阅读是个好主意。对于字符串typeb'sq_string'value 是一个'int8' dtype 的(n,1) 数组。我认为可以将其转换为 Python bytestring。有一些 SO 问题探讨了加载 hdf5 mat 文件,但我不记得是否有看过字符串。
  • 什么是f.get('etime')?它是一个组还是一个数据集?如果是一个组,它有任何键吗?
  • 试试np.array(f.get('etime'))。将其加载为数组;之后我们也许可以“解码”它,就像我在 In[138] 中所做的那样。
  • 让我们改进np.array(f.get('etime'), dtype='&lt;u4')。或者按照`@machnic 的建议使用bytes

标签: python string matlab numpy h5py


【解决方案1】:

当我需要加载.mat 时,我使用scipy,它工作正常:

import scipy.io
mat = scipy.io.loadmat('fileName.mat')

【讨论】:

  • 听起来 OP 使用较新的 hdf5 模式保存了 .mat,而不是 loadmat 兼容模式。
  • 执行此过程时,我看不到任何字符串变量。输出:dict_keys(['__header__', '__version__', '__globals__', 'average', 'stdev', 'median', 'P90', 'P10', 'None', '__function_workspace__'])
  • No Et 或 St. 注意:不要担心 NaN - 它们应该是。
【解决方案2】:

八度音阶

>> x = 1:10;
>> y = reshape(1:12, 3,4);
>> et = '0101121200000';
>> xt = 'a string';
>> save -hdf5 testh5.mat x y et xt

在一个 numpy 会话中:

In [130]: f = h5py.File('testh5.mat','r')
In [131]: list(f.keys())
Out[131]: ['et', 'x', 'xt', 'y']
In [132]: list(f['y'].keys())
Out[132]: ['type', 'value']
In [133]: f['x/type'].value
Out[133]: b'range'
In [134]: f['y/type'].value
Out[134]: b'matrix'
In [135]: f['y/value'].value
Out[135]: 
array([[ 1.,  2.,  3.],
       [ 4.,  5.,  6.],
       [ 7.,  8.,  9.],
       [10., 11., 12.]])
In [136]: f['et/type'].value
Out[136]: b'sq_string'
In [137]: f['et/value'].value
Out[137]: 
array([[48],
       [49],
       [48],
       [49],
       [49],
       [50],
       [49],
       [50],
       [48],
       [48],
       [48],
       [48],
       [48]], dtype=int8)
In [138]: f['et/value'].value.ravel().view('S13')
Out[138]: array([b'0101121200000'], dtype='|S13')
In [139]: f['xt/value'].value.ravel().view('S8')
Out[139]: array([b'a string'], dtype='|S8')
In [140]: f.close()

how to import .mat-v7.3 file using h5py

Opening a mat file using h5py and convert data into a numpy matrix

====

bytes 也适用于我的文件

In [220]: bytes(f['xt/value'].value)
Out[220]: b'a string'
In [221]: bytes(f['et/value'].value)
Out[221]: b'0101121200000'

【讨论】:

  • 这对我不起作用。使用list(f['average'].keys()) 时出现以下错误:AttributeError: 'Dataset' object has no attribute 'keys'
  • 好的,在我的版本中,f['average'] 是一个包含 2 个数据集的组。显然在你的f['average'] 中是数据集本身。我没有你的文件,所以不能自己探索。
  • 'average' 是一个 9 x 365 的矩阵,主要包含 NaN 和一些浮点数。
  • 四处挖掘我发现 MATLAB v7.3 和 Octave 的 hdf5 之间存在更大的差异。如果没有示例文件,我将无能为力。
  • @hpualj 我在 MATLAB 中添加了数据的图像。我找不到附加 .mat 文件的方法
【解决方案3】:

如果您不介意 etimestime 的变量类型存储在 file.mat 中,并且可以将它们存储为类型 char 而不是 string,您可以通过以下方式在 Python 中读取它们:@ 987654326@。在你的情况下:

data = {
    "average": np.array(f.get('average')),
    "median": np.array(f.get('median')),
    "stdev": np.array(f.get('stdev')),
    "P10": np.array(f.get('p10')),
    "P90": np.array(f.get('p90')),
    "St": bytes(f.get('stime')[:]).decode('utf-8'),
    "Et": bytes(f.get('etime')[:]).decode('utf-8')
}

我确信还有一种读取string类型的方法,但这可能是最简单的解决方案。

【讨论】:

    猜你喜欢
    • 2021-02-23
    • 2015-07-03
    • 1970-01-01
    • 2020-11-18
    • 1970-01-01
    • 2017-04-23
    • 2016-01-25
    • 2014-10-17
    • 2018-11-04
    相关资源
    最近更新 更多