【问题标题】:merge structure field cells in matlab在matlab中合并结构字段单元格
【发布时间】:2015-05-15 05:39:38
【问题描述】:

我想合并结构字段以防我进行部分计算,以便稍后填充整个结构字段单元格。

将结果根据索引放入单元格中,如下所示:

for i=3:4;
results1.index{i}=i;
results1.sqr{i}=i*i;
end
for i=1;
results2.index{i}=i;
results2.sqr{i}=i*i;
end

分别给予:

results1 = 

    index: {[]  []  [3]  [4]}
      sqr: {[]  []  [9]  [16]}

results2 = 

    index: {[1]}
      sqr: {[1]}

有没有办法合并得到的结构以获得

allresults.index={[1] [] [3] [4]}
allresults.sqr={[1] [] [9] [16]}

我可以避免结果重叠,因此在值冲突的情况下不解决冲突或覆盖(例如,没有一个单元格为空)就可以了。 请注意,在较大的数据集中,单元格不仅限于标量,还可能包含单元格或其他类型。

【问题讨论】:

  • 您是否总是事先知道单元格所在位置的索引?例如,您是否知道results1 将填充单元格3 和4,而results2 将填充单元格1?如果没有这些信息,如果您将两个字段的内容用于两个结构,那么如何将单元格连接在一起会很模糊。
  • 是的,正如我提到的,结果是根据索引放入单元格中的,因此 3:4 上的循环将分别填充单元格 3 和 4。这就是为什么results1 有两个空的前导单元格。

标签: matlab merge structure field


【解决方案1】:

你可以先写一个小辅助函数来合并单元格:

function R = mergeCells(A,B)
R = {};
IA = ~cellfun('isempty',A);
IB = ~cellfun('isempty',B);
R(IA) = A(IA);
R(IB) = B(IB);
end

然后循环调用合并字段

for k = 1:numel(F), 
    f = F{k}; 
    allresults.(f) = mergeCells(results1.(f), results2.(f)); 
end

【讨论】:

  • 这很好,尤其是您如何使用cellfun 来查找非空单元格。
【解决方案2】:

这里有一个函数来完成这个。我认为它是相当笼统的,它确实处理字符串,但假设没有冲突。如果struct 具有不同的字段名称或不同数量的字段,它将失败。我无法告诉您有关性能或是否有更好的方法来做到这一点的任何事情。

function T = structCat(re1,re2)
F=fieldnames(re1);
for i=1:length(F) %// Do one field name at a time
    t1=re1.(F{i}); %// These are the individual cell arrays we are combining
    t2=re2.(F{i});
    if length(t2)>length(t1)
        %// This loop just makes t1 be the longest cell array, it's a bit messy though
        t1a=t1;
        t1=t2;
        t2=t1a;
    end
    T.(F{i})=t1; %// Now we know t1 is longer, set the new array to t1 initially
    for j=1:length(t2) %// Do each element of t2 individually
        if ~exist(T.(F{i}){j},'var') %// see if there is an element of t2 to insert into T
            T.(F{i}){j}=t2{j}; %// if there is, insert it!
        end
    end 
end
end

例如,用法是

for i=3:4;
    re1.index{i}=i;
    re1.index2{i}=i^2;
    re1.strings{i}='dafsd';
    re1.mat{i}=[i;2*i;3*i];
end
for i=1;
    re2.index{i}=i;
    re2.index2{i}=i^2;
    re2.strings{i}='hmmm';
    re2.mat{i}=[i;2*i;3*i].^2;
end

T=structCat(re1,re2)

导致

T = 
      index: {[1]  []  [3]  [4]}
     index2: {[1]  []  [9]  [16]}
    strings: {'hmmm'  []  'dafsd'  'dafsd'}
        mat: {[3x1 double]  []  [3x1 double]  [3x1 double]}

您还应该查看this questionthis entry in the Matlab File Exchange,尽管我认为它们做的事情略有不同。

【讨论】:

    【解决方案3】:

    两个答案都有效。因此,我将 Mohsen 的简单性与 David 的一步法结合起来:

    function C = structCat2(A,B)
    
    F=fieldnames(A);
    for k = 1:numel(F), 
        f = F{k}; 
        IA = ~cellfun('isempty',A.(f));
        IB = ~cellfun('isempty',B.(f));
        C.(f)(IA) = A.(f)(IA);
        C.(f)(IB) = B.(f)(IB);
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-27
      • 1970-01-01
      • 2012-12-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多