【问题标题】:Append data to a saved variable using matfile()使用 matfile() 将数据附加到保存的变量
【发布时间】:2018-03-07 07:44:37
【问题描述】:

我有一些随机的 2D 数据 fuffa 保存到文件 fuffalo

fuffa=rand(10,10);
save('fuffalo','fuffa', '-v7.3')

然后,我会执行一个循环,该循环生成我想要(在第三维中)附加到已保存变量的其他 fuffa 数据。为此,我尝试应用this 建议:

m1 = matfile('fuffalo.mat', 'Writable', true);

for ii=1:3
   fuffa2=rand(10,10);    
   m1.fuffa(1:10,1:10,end+1)=fuffa2;
end

但是,在ii=2 我收到以下错误:

变量 'fuffa' 在文件中有 2 个维度,这与索引下标中的 3 个维度不匹配。

如何说服 MATLAB 在第三维中追加?

【问题讨论】:

  • 你能在第一维追加吗? fuffa = rand(1,10,10)
  • 是的,我猜。你知道为什么会这样吗?
  • 因为 matlab 会在前两个之后自动删除尾随单例维度。
  • 不是(仅)在ii=2,您也应该收到ii=1 的错误
  • 前两个维度。不是条目。所以 [20 x 1] 向量保持 [20 x 1] 向量。但是 [20 x 20 x 1] 矩阵变成了 [20 x 20] 矩阵。第三个,单例,维度被删除。这是 matlab 的怪癖之一。

标签: matlab append mat-file


【解决方案1】:

因为您访问的是磁盘上的文件,而不是工作区变量,所以您可能会遇到扩展维数的问题。在处理存储在内存中的变量时,您不会遇到此问题(例如,如果您使用 load 而不是 matfile)。

为避免这种情况,最好的方法是pre-allocation。我将假设这是对您的实际问题的简化,并且您需要能够对潜在的 2D 数组进行此类 3D 扩展。

在这种情况下,只需使用cat 在第三维连接:

fuffa=rand(10,10);
save('fuffalo','fuffa', '-v7.3')
m1 = matfile('fuffalo.mat', 'Writable', true);
for ii=1:3
    fuffa2=rand(10,10);
    % Concatenating in the 3rd dimension, avoiding used 'end' which 
    % assumes that dimension already exists
    m1.fuffa=cat(3,m1.fuffa,fuffa2);
end
% m1.fuffa <10x10x4 double>

请注意,通过这样做,您会将整个 .mat 数据放入内存中以进行连接,从而违背了matfile() 的观点。但是,您之前的方法将面临同样的问题,因为在 docs 我们看到:

使用 end 关键字作为索引的一部分会导致 MATLAB 将整个变量加载到内存中。

如前所述,使用预分配可能会更好!

【讨论】:

  • 该文件是一个 HDF5 容器。其中的数据具有固定的维度,但您也可以先存储一个 3D 矩阵 10x10x2 并覆盖第二个 fuffa。然后在容器中将其指定为 3D,您应该能够附加到它。
  • matfile() 函数允许用户直接从磁盘上的文件而不是内存中访问数据。再次,“工作区”可能是我错误的选择。有关更多信息,请参阅docs,但基本上这比使用load 处理大型数据集要快,因为数据永远不会完全加载到内存中。所以MAT-file 对象在工作区中,但这不包含数据,只是引用它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多