Arrays matlab中的结构

Arrays matlab中的结构,arrays,matlab,structure,Arrays,Matlab,Structure,%范例 clear all a1 = struct('data1',rand(12,2),'data2',rand(12,2),'data3',rand(12,3)); a2 = struct('data1',rand(12,2),'data2',rand(12,2),'data3',rand(12,3)); a3 = struct('data1',rand(12,2),'data2',rand(12,2),'data3',rand(12,3)); a4 = struct('data1',ran

%范例

clear all
a1 = struct('data1',rand(12,2),'data2',rand(12,2),'data3',rand(12,3));
a2 = struct('data1',rand(12,2),'data2',rand(12,2),'data3',rand(12,3));
a3 = struct('data1',rand(12,2),'data2',rand(12,2),'data3',rand(12,3));
a4 = struct('data1',rand(12,2),'data2',rand(12,2),'data3',rand(12,3));
假设结构代表一个时间序列,其中a1代表 前5天(例如),a2代表第5-10天,依此类推。。。我正在努力 组合结构中的每个字段名,这样我就有了一个连续的序列(而不是将它们拆分为不同的结构。例如

data1=[a1.data1;a2.data1;a3.data1;a4.data1]

然后对数据2和数据3执行相同的操作


最好的方法是什么?

最好的方法是预先将结构定义为结构数组:

a(1) = struct('data1',rand(12,2),'data2',rand(12,2),'data3',rand(12,3));
a(2) = struct('data1',rand(12,2),'data2',rand(12,2),'data3',rand(12,3));
a(3) = struct('data1',rand(12,2),'data2',rand(12,2),'data3',rand(12,3));
a(4) = struct('data1',rand(12,2),'data2',rand(12,2),'data3',rand(12,3));
这使您可以非常轻松地获取数据:

cat(1,a.data1)
但如果坚持使用N结构,请尝试以下方法:

function so3
    a1 = struct('data1',rand(12,2),'data2',rand(12,2),'data3',rand(12,3));
    a2 = struct('data1',rand(12,2),'data2',rand(12,2),'data3',rand(12,3));
    a3 = struct('data1',rand(12,2),'data2',rand(12,2),'data3',rand(12,3));
    a4 = struct('data1',rand(12,2),'data2',rand(12,2),'data3',rand(12,3));

    s{1} = struct2cell(a1);
    s{2} = struct2cell(a2);
    s{3} = struct2cell(a3);
    s{4} = struct2cell(a4);

    N = numel(fieldnames(a1));
    data = cell([1 N]);
    for i=1:N
        data{i} = cell2mat(cellfun(@(x){x{i}'},s));
    end

end

@Andrey说得对,“最好的方法是预先将结构定义为结构数组”。他的答案是完整的。但我不得不给出以下更简洁的代码来处理“坚持使用N个结构”的情况。它假定它们的名称都以foo开头,并以数字结尾,例如foo1、foo2、foo21,它将导致数据字段按照foo名称的字母顺序排列

% first make some data
foo1 = struct('data1',rand(12,2),'data2',rand(12,2),'data3',rand(12,3));
foo2 = struct('data1',rand(12,2),'data2',rand(12,2),'data3',rand(12,3));
foo3 = struct('data1',rand(12,2),'data2',rand(12,2),'data3',rand(12,3));
foo4 = struct('data1',rand(12,2),'data2',rand(12,2),'data3',rand(12,3));
现在,我们在工作区中得到一个变量列表,这些变量以foo开头,以某个数字结尾,并将它们放入一个单元格中,然后计算该单元格的逗号分隔连接,将foo设置为该值

varstarter = 'foo';
varlist = who('-regexp', ['^' varstarter '[0-9]+']);
try
    eval([varstarter '=[' sprintf('%s,',varlist{:}) '];']);
catch
    warning('Could not concatenate variables starting with "%s".',varstarter); 
end
这让我们可以直接使用@Andrey的答案:

data1 = cat(1, foo.data1);
data2 = cat(1, foo.data2);
data3 = cat(1, foo.data3);
编辑(附录):您可以通过循环遍历foo的字段名,并将相同名称的变量分配给concatation,从而使最后一步更加自动化。如果您想要不同的名称,代码不难修改。还可以添加一个检查,以确保该内容实际具有字段

if ~isstruct(foo)
    warning('Variable "%s" is of an unexpected type.',varstarter);
else
    varfields = fieldnames(foo);
    for k=1:length(varfields)
        eval([varfields{k} '=cat(1, ' varstarter '.' varfields{k} ');']);
    end
end
出于避免显式循环(因为这很有趣)的精神,下面是else语句中位的等效代码:

varfields = repmat(fieldnames(foo)',2,1);
eval(sprintf(['%s=cat(1,' varstarter '.%s);'],varfields{:}));

+1-非常好!也许你应该添加一个案例来检查变量内的数据是否符合预期。这是一种防御性编程。答案很好。从这一点上可以用循环完成最后一个阶段。因此,首先使用“FieldName”来查找数组的名称,然后为每个数组生成一个与预期类似的变量如上图所示?@Andrey谢谢。我为连接添加了一个catch,在新的“提取自动化”部分中,我在查找字段之前检查它是否是一个结构。@user1155751是的,如果我理解你的话,这当然是可能的。我在答案中添加了一个小部分。