【问题标题】:Is there a way to remove all but a few desired fields from a struct in MATLAB?有没有办法从 MATLAB 中的结构中删除除少数所需字段之外的所有字段?
【发布时间】:2013-02-01 14:34:30
【问题描述】:

所以我有几个结构,其中包含使用的数据是十几个脚本。问题是对于每个脚本,我只需要少数变量,其余的我可以忽略。我正在使用大量数据(数据),MATLAB 经常给我内存不足的错误,所以我需要从结构中删除所有不必要的字段。

目前我有一个包含所有不需要的字段的单元格,然后我在结构上调用 rmfield。但是结构中的字段经常发生变化,不断更新不需要的字段列表变得很痛苦。那么有没有办法告诉 MATLAB 只保留我想要的那些字段并删除其他所有内容,即使我不知道其他所有内容是什么?

这是一个例子,

  • 结构 1 具有:A、B、C、D、E 字段
  • 结构 2 具有:A、B、C、D、E、F 字段
  • 结构 3 具有:A、B、C、D、E、F、G、H、I 字段

有时 Struct 3 可能只有 A 到 G。

我只想保留 A、B 和 C 字段,并从所有结构中删除所有其他数据。

【问题讨论】:

    标签: matlab matlab-struct


    【解决方案1】:

    这是一种方法:

    1. 使用fieldnames获取所有字段名的列表
    2. 从列表中删除您要保留的那些
    3. 删除列表中剩余的所有内容

    例子

    s.a=1
    s.b=2
    s.c=3
    s.d='chitchat'
    
    tokeep = {'a','b'}
    
    f=fieldnames(s)
    
    toRemove = f(~ismember(f,tokeep));
    
    s = rmfield(s,[toRemove])
    

    【讨论】:

    • 所以我尝试使用 fieldnames() 但无法弄清楚如何删除我想要的那些。我使用正则表达式进行搜索和替换,但 rmfield 显然不喜欢我的替换。对于从单元格中删除字符串,您还有其他建议吗?
    • @DennisJaheruddin:我已经稍微缩短了您的示例。希望你不要介意。
    【解决方案2】:

    您可以将结构所需的字段复制到函数中的新变量中。

    function newVar = getABC(strct)
        newVar.A = strct.A;
        newVar.B = strct.B;
        newVar.C = strct.C;        
    end
    

    strct 不会被复制到内存中,因为you will not be manipulating it

    MATLAB 使用一种通常称为“写时复制”的系统来避免生成 函数工作区中输入参数的副本,直到或 除非您修改输入参数。如果不修改输入 参数,MATLAB 将避免复制。

    你可以从内存中得到newVar,然后是clear strct


    Fred 的通用版本:

    function newVar = getFields(oldVar, desiredCell)
        for idx = 1:length(desiredCell)
        newVar.(desiredCell{idx}) = oldVar.(desiredCell{idx});
    end
    

    【讨论】:

    • 结构体不能复制到函数工作区,但它必须仍然在主工作区的内存中。因此我认为所需的最小内存可能仍然是 struct 和 newstruct 的大小。
    • @DennisJaheruddin 是的,但是在离开函数后strct 可以立即从内存中删除。因此,只有newStrct 会占用内存。
    • 我喜欢它,我会用它。谢谢!
    • 如果有人感兴趣,我使用了答案,但对其进行了一些修改以使其更通用。
      function newVar = getFields(oldVar, desiredCell)<br/> for i=1:length(desiredCell)<br/> newVar.(desiredCell{i}) = oldVar.(desiredCell{i});<br/> end
      这允许我传入任何字符串单元格我关心的变量并获取数据。感谢 HebeleHododo 的提示!
    • @Fred 这是一个很好的概括。我将其编辑到我的帖子中。
    【解决方案3】:

    1) 假设你有一个结构 S

    2) 您只想保留 S 的前三个字段并删除所有其他字段

    fieldsS = fieldnames(S);
    S = rmfield(S,fieldsS(4:end));
    

    【讨论】:

      【解决方案4】:

      MATLAB 中的 rmfield 方法比较慢,所以在处理大型结构时最好避免使用它。

      这个 MATLAB 文件交换项:kpfield 基本上是 rmfield 的倒数,应该完全按照您的要求工作。

      它通过根据字段名中是否存在字段创建逻辑数组,将结构转换为元胞数组,然后仅保留所需的索引。然后将修改后的元胞数组转换回结构体。

      免责声明:我写了 kpfield,因为我遇到了完全相同的问题。

      【讨论】:

        【解决方案5】:

        我成功加载了结构体——物理上删除了我想删除的字段,然后重新保存了结构体。

        删除工作区中的字段不会从原始结构中删除它们 - 因此需要重新保存。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-06-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多