按 prepending/postpending NaN 对齐元胞数组中的多个数组
Aligning multiple arrays in a cell array by prepending/postpending NaNs
我正在尝试对齐元胞数组中的数组,而 prepending/postpending 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
我正在尝试对齐元胞数组中的数组,而 prepending/postpending 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