将 Numpy 结构数组保存到 *.mat 文件

Posted

技术标签:

【中文标题】将 Numpy 结构数组保存到 *.mat 文件【英文标题】:Saving Numpy Structure Array to *.mat file 【发布时间】:2016-06-12 21:56:03 【问题描述】:

我正在使用numpy.loadtext 从一个 CSV 数据文件生成一个结构化的 Numpy 数组,我想将它保存到一个 MAT 文件中,供那些更熟悉 MATLAB 而不是 Python 的同事使用。

示例案例:

import numpy as np
import scipy.io

mydata = np.array([(1, 1.0), (2, 2.0)], dtype=[('foo', 'i'), ('bar', 'f')])
scipy.io.savemat('test.mat', mydata)

当我尝试在这个数组上使用scipy.io.savemat 时,会抛出以下错误:

Traceback (most recent call last):
  File "C:/Project Data/General Python/test.py", line 6, in <module>
    scipy.io.savemat('test.mat', mydata)
  File "C:\python35\lib\site-packages\scipy\io\matlab\mio.py", line 210, in savemat
    MW.put_variables(mdict)
  File "C:\python35\lib\site-packages\scipy\io\matlab\mio5.py", line 831, in put_variables
    for name, var in mdict.items():
AttributeError: 'numpy.ndarray' object has no attribute 'items'

我是 Python 新手(充其量),但我假设这是因为 savemat 设置为处理 dicts 并且 Numpy 的结构化数组的结构不兼容。

我可以通过将我的数据拉入字典来解决这个错误:

tmp = 
for varname in mydata.dtype.names:
    tmp[varname] = mydata[varname]

scipy.io.savemat('test.mat', tmp)

可以很好地加载到 MATLAB 中:

>> mydata = load('test.mat')

mydata = 

    foo: [1 2]
    bar: [1 2]

但这似乎是一种非常低效的方法,因为我正在复制内存中的数据。有没有更聪明的方法来做到这一点?

【问题讨论】:

不要担心潜在的数据副本。 savemat 必须处理数据,以便它可以将其写入 MATLAB 兼容的形式。文件写入比数组复制花费更多时间。专注于最好的 MATLAB 数据结构。 【参考方案1】:

你可以scipy.io.savemat('test.mat', 'mydata': mydata)

这将创建一个结构体mydata,文件中包含foobar 字段。

或者,您可以将循环打包在 dict 理解中:

tmp = varname: mydata[varname] for varname in mydata.dtype.names

我不认为创建临时字典会复制内存中的数据,因为 Python 通常只存储引用,特别是 numpy 会尽可能尝试在原始数据中创建视图。

【讨论】:

在快速测试中,保存tmp 比保存mydata 更快。但时间不应该是这里的大问题。

以上是关于将 Numpy 结构数组保存到 *.mat 文件的主要内容,如果未能解决你的问题,请参考以下文章

将字典保存到文件(numpy 和 Python 2/3 友好)

如何将各种尺寸的数组的Python列表保存到mat文件[重复]

如何将数组从.txt文件导入到numpy数组?

如何使用 numpy.savez 将带有子数组的数组保存到单独的 .npy 文件中

将不同长度的numpy数组保存到同一个csv文件的最佳方法是啥?

如何在keras中通过numpy数组初始化图层