问题描述
我试图在单元格数组中对齐数组,同时在前面/后面添加 NaN 以匹配这样的数组大小,例如:
%setting up data
A = [0.01 0.02 0.03 0.01 0.60 0.90 -1.02];
B = [0.03 0.01 0.60 0.90];
C = [0.03 0.01 0.60 0.90 -1.02 0.03 -1.02];
CellABC = {A,B,C};
预期的输出是这样的:
CellABC = {[0.01 0.02 0.03 0.01 0.60 0.90 -1.02 NaN NaN ],...
NaN NaN 0.03 0.01 0.60 0.90 NaN NaN NaN ],...
NaN NaN 0.03 0.01 0.60 0.90 -1.02 0.03 -1.02]};
这只是一个例子。在我的实际数据中,我有一个 1x100 元胞数组,其中包含大小从 1x400 到 1x1400 的数组。
我已经试过了:
[~,idx] = max(cellfun(@numel,CellABC)); %index of maximum no. of entries in CellABC
for i=1:length(CellABC)
[d1,d2] = findsignal(CellABC{idx},CellABC{i},'Metric','absolute');
tmp = NaN(size(CellABC{idx})); %initializing with NaNs
tmp(d1:d2) = CellABC{i}; %saving the array as per indices of found values
CellABC{i} = tmp; %Updating the cell array
end
这将正确对齐 CellABC{2},但后置 NaN 的数量不正确。此外,这不会在 CellABC{1} 的末尾提供后置的 NaN,而在 CellABC{3} 的开头不会提供后置的 NaN。我理解 findsignal 函数在这种情况下没有用的原因,因为我们没有一个包含完整数据的数组作为 findsignal 的第一个输入参数。我怎样才能做到这一点?
我还研究了 alignsignals 函数,但它仅适用于两个信号。我无法弄清楚如何在我的情况下为 100 个信号实现这一点。
如何解决这个问题?
解决方法
示例数据相对简单,但如果真实数据过于分散,您可能需要多个循环中的多个模板。
A = [0.01 0.02 0.03 0.01 0.60 0.90 -1.02];
B = [0.03 0.01 0.60 0.90];
C = [0.03 0.01 0.60 0.90 -1.02 0.03 -1.02];
CellABC = {A,B,C};
% find longest anyway
[~,I]=max(cellfun(@(x) numel(x),CellABC));
% find lags and align in two pass
% 1st pass
lags=zeros(numel(CellABC),1);
for idx=1:numel(CellABC)
if idx==I,continue; end
[r,lag]=xcorr(CellABC{I},CellABC{idx});
[~,lagId]=max(r);
lags(idx)=lag(lagId);
end
% 2nd pass
out=nan(numel(CellABC),max(arrayfun(@(x) numel(CellABC{x})+lags(x),1:numel(CellABC))));
for idx=1:numel(CellABC)
out(idx,lags(idx)+1:lags(idx)+numel(CellABC{idx}))=CellABC{idx};
end
out =
0.0100 0.0200 0.0300 0.0100 0.6000 0.9000 -1.0200 NaN NaN
NaN NaN 0.0300 0.0100 0.6000 0.9000 NaN NaN NaN
NaN NaN 0.0300 0.0100 0.6000 0.9000 -1.0200 0.0300 -1.0200