从MAT文件中读取结构化变量

时间:2014-06-10 23:57:25

标签: matlab data-structures

我正在进行一项涉及超过1000个案例模拟的分析。我也为每个案例提取了大量数据(大约70MB)。目前我将每个案例的结果保存为:

Vessel.TotalForce
Vessel.WindForce
Vessel.CurrentForce
Vessel.WaveForce
Vessel.ConnectionForce
...

Line1.EffectiveTension
Line1.X
Line1.Y

Line2.EfectiveTension
Line2.X
Line2.Y
...

save('CaseNo1.mat')

现在,我需要对CaseNo1.matCaseNo1000执行分析。最初,我计划通过加载其中的所有案例然后使用Database.mat访问任何变量来创建h5read文件。这样Matlab不需要一次加载所有数据。但是,我现在担心我的数据库文件太大了。

有没有办法可以从单个案例文件中读取结构化变量,例如CaseNo1.mat而不在内存中加载CaseNo1.mat文件。

Matlab示例显示直接从MAT文件加载变量而不加载整个MAT文件。但我不确定如何以相同的方式阅读结构数据。

x=load('CaseNo1.mat','Line1.X')

说找不到Line1.X。但它就在那里。访问数据的命令不正确。还尝试使用h5read,但它说CaseNo1.mat不是HDF5文件。

任何人都可以帮忙解决这个问题。

除此之外,如果有任何关于进行此类数据密集分析的建议,我也将不胜感激。

4 个答案:

答案 0 :(得分:1)

编辑:这个答案有效,但实际上并没有解决OP问题中提出的问题。我以为我用matfile生成了一个我可以访问的句柄,但我错了。有关详细信息,请参阅我的其他答案。

您可以使用matfile,如下所示:

myMatFileHandle = matfile('caseNo1.mat');
thisVessel = myMatFileHandle.vessel;

此外,从我能看到的一点点来看,您似乎正在进行大批量分析。请记住在适用时使用sparse,并且如果可能的话,通常会避免循环内的条件。

祝你好运!

答案 1 :(得分:1)

我错了!我已经将我的旧答案留给了上下文,不过我已经编辑过它来引用这个。我之前认为我曾经以这种方式使用过matfile(),但我还没有。我只是进行了彻底的搜索并运行了一些测试用例。您实际上遇到了Matlab处理和引用存储在.mat文件中的结构的方式的限制。但是,有一个解决方案。它确实涉及对原始代码的一些重构,但它不应该过于令人震惊。

Vessel_TotalForce 

Vessel_WindForce 

Vessel_CurrentForce 

Vessel_WaveForce

Vessel_ConnectionForce 

... 

Line1_EffectiveTension 

Line1_X 

Line1_Y 

Line2_EfectiveTension 

Line2_X 

Line2_Y 

... 

save('CaseNo1.mat')

然后访问,只需像以前一样使用matfile(或加载)。像这样:

Vessel_WaveForce = load('CaseNo1.mat'', 'Vessel_WaveForce')

重要的是要注意,这种限制似乎不是由您在程序中选择做的任何事情引起的,而是由Matlab与其交互的方式强加的。 ;当它们包含结构时的本机存储文件。

答案 2 :(得分:1)

以结构化格式存储数据的目的是:

  1. 待办事项
  2. 简易脚本后处理器,在所需的一个数据集下循环数据。
  3. 要在MAT文件中存储包含整数,浮点和字符串变量的结构化数据集,并且能够使用h5read命令只读取所需的变量。 Matlab load命令无法从MAT文件中的存储数据读取超出第一级的变量。 h5write无法写string个变量。因此需要解决这个问题。

    为此,我使用了以下方法:

    filename = 'myMatFile';
    Vessel.TotalForce = %store some data
    Vessel.WindForce = %store some data
    Vessel.CurrentForce = %store some data
    Vessel.WaveForce = %store some data
    Vessel.ConnectionForce = %store some data
    ...
    
    Lin1.LineType = 'Wire'
    Line1.ArcLength_0.EffectiveTension = %store some data
    Line1.ArcLength_50.EffectiveTension= %store some data
    Line1.ArcLength_100.EffectiveTension= %store some data
    
    Lin2.LineType = 'Chain'
    Line2.ArcLength_0.EffectiveTension= %store some data
    Line2.ArcLength_50.EffectiveTension= %store some data
    Line2.ArcLength_100.EffectiveTension= %store some data
    
    save([filename '_temp.mat']);
    
    PointToMat=matfile([filename '.mat'],'Writable',true);
    PointToMat.(char(filename)) = load([filename '_temp.mat']);
    
    delete([filename '_temp.mat']);
    

    现在要从创建的MAT文件中读取,我们可以像往常一样使用h5read。要为Line1提取EffectiveTension,ArcLength_0:

    EffectiveTension = h5read([filename '.mat'],['/' filename '/Line1/ArcLength_0/EffectiveTension']);
    

    对于字符串变量,h5read返回与每个字符对应的十进制值。要获取我使用的实际字符串:     name = char(h5read([filename' .mat'],[' /' filename' / Line1 / LineType']);

    在我的数据集上尝试了这个大约200MB的方法,我可以很快地处理它们。希望有一天能帮助别人。

答案 3 :(得分:1)

简答: 使用'-v7.3'选项将数据保存到MAT文件中后,使用h5read(filename, '/Line2/X')之类的内容只读取一个结构字段。您甚至可以部分读取数组,例如:

s.a = 1:100;
save('test.mat', '-v7.3', 's');
clear
h5read('test.mat', '/s/a', [1 10], [1 5], [1 3])

返回1:100数组的每个第三个元素,从第10个元素开始并返回5个值:

 10    13    16    19    22

答案很长: 有关更详细的代码和主题报道,请参阅answer by @Amitava