【问题标题】:Reading structured variable from MAT file从 MAT 文件中读取结构化变量
【发布时间】:2014-07-31 21:45:27
【问题描述】:

我正在执行一项涉及对 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 执行分析。最初我计划通过在其中加载所有案例然后使用h5read 访问任何变量来创建一个Database.mat 文件。这样,Matlab 就不需要一次加载所有数据。但是,我现在担心我的数据库文件会太大。

有什么方法可以从单个案例文件中读取结构化变量,例如CaseNo1.mat,而无需将CaseNo1.mat 文件加载到内存中。

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

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

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

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

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

【问题讨论】:

标签: matlab data-structures


【解决方案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】:

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

    你可以像这样使用 matfile:

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

    另外,从我所看到的一点点来看,您似乎在进行大容量分析的正确轨道上。只要记住在适用的情况下使用sparse,并且通常尽可能避免在循环内使用条件。

    祝你好运!

    【讨论】:

    • 谢谢弗莱奇。只是想知道,在这种情况下,vessel 中的所有变量是加载到内存中还是只是一个句柄?
    • 这与thisVessel = load('CaseNo1.mat','vessel') 有何不同。我使用whos检查了内存,它显示两种情况下使用的内存相同,非常大。
    【解决方案3】:

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

    1. 待整理
    2. 简单的脚本后处理器,它需要在一个数据集下循环数据。

    寻求在 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 的数据集上尝试了这种方法,我可以很快地处理它们。希望有一天这会对某人有所帮助。

    【讨论】:

      【解决方案4】:

      简答: 使用'-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 了解更详细的代码和主题覆盖范围。

      【讨论】:

        猜你喜欢
        • 2016-07-23
        • 2017-11-26
        • 2018-09-19
        • 1970-01-01
        • 2015-04-06
        • 2014-06-07
        • 2013-03-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多