如何使用scipy.io.savemat将内容添加到.mat文件中?

11

当我使用savemat命令时,它倾向于覆盖文件。有可能以追加而非覆盖的方式进行操作吗? 我知道一个解决方法是把所有内容放到一个列表中,然后将其转换为字典。但对我来说这行不通,因为我试图提高RAM效率。在网上搜索后,我找到了这个如何在使用scipy.io.savemat()函数时不覆盖.mat文件?

但这个方法也不行,因为它涉及每次循环都要将数据文件加载到RAM中进行追加,从速度角度看似乎很愚蠢。

我想过将数据追加到numpy二进制文件中,然后将其加载并保存到.mat文件中。但我不确定这是否比第一个选项更节约RAM。

谢谢!


1
你是在文件中添加新变量,还是在现有变量中添加值?“每个循环”是什么意思?你是想逐步写入数据到文件中吗? - hpaulj
3个回答

4
根据savemat的文档:
文件名:字符串或文件对象
因此,您可以以附加模式打开文件并编写内容,例如:
io.savemat('temp.mat',{'data':np.ones(10)})  # write
with open('temp.mat','ab') as f:
    io.savemat(f, {'newdata':np.arange(5)})   # append
print io.loadmat('temp.mat').keys()           # read
# dict_keys(['data', '__globals__', 'newdata', '__header__', '__version__'])

或者完整描述:
{'data': array([[ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.]]),
 '__globals__': [],
 'newdata': array([[0, 1, 2, 3, 4]]),
 '__header__': b'MATLAB 5.0 MAT-file Platform: posix, Created on: Fri Mar 13 14:14:33 2015',
 '__version__': '1.0'}

https://github.com/scipy/scipy/blob/master/scipy/io/matlab/mio5.py#L34的一个注释中提到,如果数据文件中有函数,则追加可能会出现问题,但这表明如果我们仅保存数组,则追加不是问题。 但或许需要进一步搜索scipy的问题。


2
它创建了文件,但由于某种原因我无法加载它。我得到一个TypeError:期望miINT32作为数据类型。您可以将数据附加到同一字典键。但是您不能附加新的字典键和新数据,这正是我想要做的。我会将其标记为答案,因为它回答了我的问题,但并没有解决我的问题。 - entropy4money
我基本上能够使用建议的方法。但是,如果文件中已经存在特定的变量名,则该文件将变得无法读取。 - Vik
是的,我进行了一项测试,当存在多个相同的键时,您会收到“TypeError:Expecting miINT32”错误。 - Monica Heddneck
这里解决方案中的示例运行良好。但是当我在自己的numpy数组上使用它时,在尝试读取(保存后)时会出现“ValueError:未读取任何字节”的错误。 - Monica Heddneck

1

它只适用于一次附加!如果您附加两次,Matlab会出现错误“文件可能已损坏”。

scipy.io.savemat('temp.mat',{'data':np.ones(10)})  # write
with open('temp.mat','ab') as f:
    scipy.io.savemat(f, {'newdata1':np.arange(5)})   # append
with open('temp.mat','ab') as f:
   scipy.io.savemat(f, {'newdata2':np.arange(5)})   # append

0

如果你需要追加大量数据,另一个选择是:

self.upload1 = sio.loadmat(self.namedir,self.params)
sio.savemat('params_lo.mat', self.upload1)

使用此表格可以加载数据并添加新变量。注意,如果它们具有相同的名称,则不会更改其值。因此,为了纠正这种情况,我会删除所有想要更改的变量。
    self.upload = sio.loadmat(self.namedir)
    for i in self.str_vars:
       try:
          del self.upload[i]
       except:
          continue
    sio.savemat('params_lo.mat', self.upload)
    self.upload1 = sio.loadmat(self.namedir,self.params)
    sio.savemat('params_lo.mat', self.upload1)

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