關閉。這個問題需要細節或清晰。它目前不接受答案。
想改進這個問題?通過編輯此帖子添加詳細資訊并澄清問題。
7 天前關閉。
此帖已于7 天前編輯并提交審核。
改進這個問題我有很多 mat 檔案,每個檔案都包含一個s具有相同內部結構的結構陣列。這是s您從加載單個檔案中獲得的這些結構陣列之一的最小示例:
s(1).A.a=rand(3);
s(1).A.b=rand(4);
s(1).B =1;
s(2).A.a=rand(3);
s(2).A.b=rand(4);
s(2).B =10;
實際上,結構陣列有 100 個元素,以及數十個欄位和子欄位。請不要評論按原樣保存檔案的選擇。它不在我的控制范圍內,這里的問題是關于如何處理這些檔案中的資訊。
我最終希望平均這些結構陣列的每個子欄位的所有資訊,因此邏輯步驟是將它們相加(然后除以檔案數)。
我目前的解決方案是:
% initialize arrays of the same inner structure as `s`
sum_s_A_a=zeros(size(s(1).A.a,1),size(s(1).A.a,2),numel(s));
sum_s_A_b=zeros(size(s(1).A.b,1),size(s(1).A.b,2),numel(s));
sum_s_B=zeros(1,numel(s));
for jj=1:100 % loop over all 100 files (just for the example)
% load here each file that contains s
for ii=1:numel(s) ; % loop each element in s and add it to sum_s
sum_s_A_a(:,:,ii) = sum_s_A_a(:,:,ii) s(ii).A.a;
sum_s_A_b(:,:,ii) = sum_s_A_b(:,:,ii) s(ii).A.b;
sum_s_B(ii) = sum_s_B(ii) s(ii).B;
end
end
這是非常不實用的,因為 中有幾十個欄位和子欄位s,但是如果您s按照上面的定義使用,上面的最小示例適用于“單個檔案”情況
我想以與上面的 for 回圈類似的方式對所有這些檔案的資訊求和,但不寫下并將所有欄位和子欄位的名稱硬編碼為陣列名稱,并且如果可能的話不使用 for 回圈.
我不介意資訊的最終容器是結構、單元還是陣列。
uj5u.com熱心網友回復:
從您的示例開始,以便對所有A欄位求和并在此處回傳數字陣列,這是一種不使用回圈的方法:
function result = sumstruct (varargin)
v = [varargin{:}];
s = [v.A];
result = sum([s.tot1], 2);
end
并將其稱為:
result = sumstruct (s1, s2, s3);
編輯:
但是,如果您還想對其他欄位及其子欄位求和并將它們組合成一個結構,您需要使用回圈或cellfun. 這是遞回減少嵌套結構的解決方案:
function result = reduce(fcn, varargin)
fcns0 = {@(x)cat(3, x{:}), @(x)x};
switcher0 = @(tf, s)fcns0{tf 1}(s);
fcns = {@(s)fcn(s), @(s)reduce(fcn, s{:})};
switcher = @(tf, s)fcns{tf 1}(s);
c = cellfun(@(x){struct2cell(x)}, varargin);
s0 = cat(3, c{:});
s1 = reshape(s0, [], numel(varargin));
s2 = cellfun(@(x){switcher0(isstruct(x{1}), x)}, num2cell(s1, 2));
s3 = reshape(s2, size(c{1}));
s4 = cellfun(@(c){switcher(iscell(c), c)}, s3);
fnames = fieldnames(varargin{1});
result = cell2struct(s4, fnames, 1);
end
第一個引數是用于歸約的函式句柄,其余引數是結構陣列。
使用回圈加載所有檔案并使用reduce:
c = cell (1, 100);
for i = 1:100
c{i} = load('file');
end
result = reduce(@(x)sum(x, 3), c{:});
result = reduce(@(x)x ./ 100, result);
或者,您可以增量加載檔案并執行 reduce:
result = [];
for i = 1:100
s = load('file');
if i == 1
result = s;
else
result = reduce(@(x)sum(x, 3), result, s);
end
end
result = reduce(@(x)x ./ 100, result);
請注意,這里的歸約函式應該沿著陣列的第三維執行,因此它被寫為sum(x, 3).
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/405415.html
標籤:
上一篇:MATLAB回圈重構
