您的代码有几处错误:
首先,错误Struct contents reference from a non-struct array object.
首先出现在索引处,k=33
因为导入的结构没有data
字段(导入可能为空或失败)。
检查字段是否存在让代码运行完成。然后你会注意到你有 8 行是空的。
load('AIS_SEC.mat')
n=numel(AIS_SEC) ;
EmptyRows = false(n,1) ;
for k = 1:n
my_field = sprintf('X%03d', k);
if isfield( AIS_SEC{1,k} , 'data')
variable.(my_field) = AIS_SEC{1,k}.data;
else
variable.(my_field) = [] ;
EmptyRows(k) = true ;
end
end
fprintf('Number of empty rows encountered: %u\n',sum(EmptyRows))
我还冒昧地删除了不必要的括号,添加了一个空行索引计数器,并调整了sprintf
输出格式,以便您的所有字段都具有相同的长度(即使第一个字段也将具有前导零。'X001' to 'X500'
而不是'X1' to 'X500'
)。
此外,这只是从每个结构中检索第一列,因此我对其进行了修改以检索 3x,y,z
列。如果您真的只想要第一列,只需替换variable.(my_field) = AIS_SEC{1,k}.data
为variable.(my_field) = AIS_SEC{1,k}.data(:,1)
.
现在,这为您提供了一个包含 500 个字段的长结构(每个字段代表一个导入的变量)。您的问题在这一点上还不够清楚,但是如果您想要一个合并所有值的数组,那么您有 2 个选项:
1)直接在上面的代码之后,将您的结构转换为合并数组:
vararray = cell2mat(struct2cell(variable)) ;
2)如果上述步骤(最终variable
结构)不是您需要保留的,那么您可以首先避免它:
load('AIS_SEC.mat')
n = numel(AIS_SEC) ; % number of field to import
% first pass we count how many data point (if any) each structure has
EmptyRows = false(n,1) ;
npts = zeros(n,1) ;
for k = 1:n
if isfield( AIS_SEC{1,k} , 'data')
npts(k) = size( AIS_SEC{1,k}.data , 1 ) ;
else
EmptyRows(k) = true ;
end
end
% fprintf('Number of empty rows encountered: %u\n',sum(EmptyRows))
% The above allows us to preallocate the output matrix at the right size
cumpts = cumsum(npts) ;
totalNumberOfPoints = cumpts(end) ;
vararray = zeros(totalNumberOfPoints,3) ;
% first field to import
vararray( 1:cumpts(1) , : ) = AIS_SEC{1,1}.data ;
% now all the remaining ones
for k = 2:n
idx = (cumpts(k-1)+1):cumpts(k) ;
if ~isempty(idx)
vararray(idx,:) = AIS_SEC{1,k}.data ;
end
end
在这个版本中,整个结构有 2 次循环。直观地反击这样做是为了获得更好的性能。第一遍只是计算每个结构中数据点的数量(以及标记空的数据点)。由于第一遍返回的数字,我们可以在第二遍之前预先分配输出矩阵,并将每个结构数据分配到正确位置的合并数组中,而无需在每次迭代时调整输出数组的大小。