【问题标题】:Matlab load mat into variableMatlab将垫子加载到变量中
【发布时间】:2017-06-23 05:25:46
【问题描述】:

当将 .Mat 文件中的数据直接加载到变量中时,它会存储一个结构而不是变量本身。

例子:

myData.mat 包含var1var2var3

如果我这样做:

load myData.mat

它将在我的工作区中创建变量 var1、var2 和 var3。好的。

如果我将 load 返回的内容分配给变量,它会存储一个结构。这是正常的,因为我正在加载几个变量。

foo = load('myData.mat')

foo = 
  struct with fields:
    var1
    var2
    var3

但是假设我只对var1 感兴趣,我想直接存储到变量foo 中。

Load 可以选择仅从 .mat 文件中加载特定变量,但它仍然存储结构

foo = load('myData.mat', 'var1')
foo = 
      struct with fields:
        var1

我希望将var1 直接分配给foo

当然可以:

foo = load('myData.mat', 'var1')
foo = foo.var1;

但这应该是一种在一行中自动执行此操作的方法吧?

【问题讨论】:

  • 什么困扰着你? clear var1?在这种情况下,您可以使用:foo=load('myData.mat', 'var1')foo=foo.var1;
  • 困扰我的是我无法直接加载我想要的变量,必须将 foo 重新分配给 foo.var1。将使用您的提案更新问题,这比使用 clear 更好。当您仅加载一个变量时,Matlab 应该有一种特殊情况,因此它不会加载结构。

标签: matlab load


【解决方案1】:

如果 MAT 文件包含一个变量,则使用

x = importdata(mat_file_name)

【讨论】:

    【解决方案2】:

    load 不会以这种方式运行,否则 load 的行为会因您请求的变量数量而不一致,这将导致非常令人困惑的行为。

    为了说明这一点,假设您编写了一个通用程序,想要从 .mat 文件中加载所有变量,对它们进行一些修改,然后再次保存它们。您希望此程序与 any 文件一起使用,因此有些文件可能只有一个变量,而有些文件中可能存储有多个变量。

    如果load 使用了您指定的行为,那么您必须添加各种逻辑来检查文件中存储了多少变量,然后再加载和修改它。

    这是该程序在load 的当前行为下的样子

    function modifymyfile(filename)
        data = load(filename);
    
        fields = fieldnames(data);
    
        for k = 1:numel(fields)
            data.(fields{k}) = modify(data.(fields{k}));
        end
    
        save(filename, '-struct', 'data')
    end
    

    如果行为是你认为你想要的方式

    function modifymyfile(filename)
    
        % Use a matfile to determine the number of variables
        vars = whos(matfile(filename));
    
        % If there is only one variable
        if numel(vars) == 1
            % Assign that variable (have to use eval)
            tmp = load(filename, vars(1).name);
            tmp = modify(tmp);
    
            % Now to save it again, you have to use eval to reassign
            eval([vars(1).name, '= tmp;']);
    
            % Now resave
            save(filename, vars(1).name);
        else
            data = load(filename);
    
            fields = fieldnames(data);
    
            for k = 1:numel(fields)
                data.(fields{k}) = modify(data.(fields{k}));
            end
    
            save(filename, '-struct', 'data');
        end
    end
    

    我会留给读者来决定哪些更清晰和健壮。

    做你想做的事情的最佳方法就是你在问题中显示的内容。只需在加载后重新分配值

    data = load('myfile.mat', 'var1');
    data = data.var1;
    

    更新

    即使您只希望在显式指定变量时不将变量分配给struct,您仍然会出现不一致的行为,如果我的程序接受要更改的变量列表,这将变得很困难作为元胞数组

    variables = {'var1', 'var2'}
    
    data = load(filename, variables{:});    % Would yield a struct
    
    variables = {'var1'};
    
    data = load(filename, variables{:});    % Would not yield a struct
    

    【讨论】:

    • 我认为,如果您只是调用 load 而不指定要加载哪些变量,那么即使 mat 文件只有一个变量,也必须返回一个结构。但是,如果您明确传递变量列表并且只传递一个变量,那么我认为直接加载变量是可以接受的。或者让 load 接受一个标志以通过结构直接到达变量。
    • @SembeiNorimaki 第一个示例仍然会产生不一致的行为。一个标志会是一个更好的方法,但它确实给load 增加了不必要的复杂性,因为你真的可以在一行代码中在你的调用函数中做同样的事情。
    【解决方案3】:

    @Suever 是对的,但如果您希望使用单行解决方法,可以这样做:

    foo = getfield(load('myData.mat'), 'var1');
    

    【讨论】:

    【解决方案4】:

    它看起来很丑,但可以做你想做的:

    foo = subsref(matfile('myData.mat'),struct('type','.','subs','var1'))
    

    使用matfile 允许将变量部分加载到内存中,即它只加载必要的内容。函数subsref 完成索引运算符“.”的工作。在这种情况下。

    【讨论】:

    • 注意:要使用matfile,您必须使用v7.3 压缩保存您的.mat 文件:save('myData.mat','var1','var2','-v7.3')
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-16
    • 2017-07-13
    • 1970-01-01
    • 2011-01-11
    • 1970-01-01
    • 2015-11-19
    相关资源
    最近更新 更多