我有两个包含时间的数组。第一个是设备状态,指示何时打开电源,第二个阵列是发出给设备的实际命令的时间戳。见下图:
垂直虚线表示开机命令,蓝线表示设备状态(1 =开0 =关)。
我想要做的是创建一个匹配命令到设备响应的矩阵。问题是它们不是1对1。有冗余命令和额外的电源循环(来自手动操作等)。理想情况下,我想在命令列中将未命令的状态更改与NaN配对,类似地,任何不会导致状态更改为状态列中的NaN的冗余命令或命令。请参阅下面的示例数据和所需输出:
indicatesOn = [1 2 3 4 5];
commandIssue = [1.9 2.8 2.9 4.8 4.9 5.1]
matchedOutput =
NaN 1.0000
1.9000 2.0000
2.8000 NaN
2.9000 3.0000
NaN 4.0000
4.8000 NaN
4.9000 5.0000
5.1000 NaN
所以基本上命令时间在第1列中,并且上电在第2列中。命令列中的NaN表示没有前面的命令来更改状态(设备的手动操作)。 State / power-on列中的NaN表示设备没有响应该特定命令(已经打开或发出了多个命令)。
我开始尝试对此进行排序,并陷入乱七八糟的for循环和许多if / else逻辑,并认为必须有更好的方法。
感谢任何帮助!
编辑:
答案 0 :(得分:1)
我休息了一会儿,跑了几英里,然后再拿一个裂缝,这是我迄今为止最好的。
indicatesOn = [1 2 3 4 5];
cmdIssue = [1.9 2.8 2.9 4.8 4.9 5.1];
cmdIndex = arrayfun(@(x) find(cmdIssue < x,1,'last'),indicatesOn,'uniformoutput',false);
outState = indicatesOn(:);
outCmd = nan(size(outState));
usedCmds = false(size(cmdIssue(:)));
for k =1:numel(cmdIndex)
if ~isempty(cmdIndex{k})
outCmd(k,1) = cmdIssue(cmdIndex{k});
usedCmds(cmdIndex{k}) = true;
end
end
%Fix duplicate Commands (replace with NaN)
outCmd(diff(outCmd)==0) = NaN;
remCmds = cmdIssue(~usedCmds);
outCmd = [outCmd;remCmds(:)]; %Append remaining unprocessed Cmds
outState = [outState;nan(numel(remCmds),1)]; %Add NaNs to state.
%Sort the output by the min time stamp row-wise
matchedOutput = [outCmd outState];
[temp sortI] = sort(min(matchedOutput,[],2));
matchedOutput = matchedOutput(sortI,:)
导致:
matchedOutput =
NaN 1.0000
1.9000 2.0000
2.8000 NaN
2.9000 4.0000
NaN 3.0000
4.8000 NaN
4.9000 5.0000
5.1000 NaN
如果有人看到任何改进空间或逻辑漏洞让我知道。