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

16

我正在使用 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被设置为处理字典,而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]

但这似乎是一种非常低效的方法,因为我在内存中复制了数据。有没有更聪明的方法来完成这个任务?


3
不用担心潜在的数据复制问题。 savemat 函数需要操作数据,以便将其写入与 MATLAB 兼容的格式。文件写入所需时间比数组复制更长。请关注选择最佳的 MATLAB 数据结构。 - hpaulj
1个回答

17

您可以使用 scipy.io.savemat('test.mat', {'mydata': mydata}) 方法。

这会在文件中创建一个名为 mydata 的结构体,其中包含字段 foobar

或者,您可以将循环打包在字典推导式中:

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

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


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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接