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是的,如果我理解你的话,这当然是可能的。我在答案中添加了一个小部分。