Сортировать / сопоставить два столбца времен заполнения с NaN - PullRequest
3 голосов
/ 15 февраля 2012

У меня есть два массива, которые содержат времена. Первый - это состояние устройства, указывающее, когда было включено питание, а второй массив - отметки времени фактической команды, выданной устройству. Смотрите сюжет ниже: enter image description here

Вертикальные пунктирные линии показывают команды включения питания, а синяя линия представляет состояние устройства (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 в столбце «Команда» будет означать, что не было предшествующей команды для изменения состояния (ручное управление устройством). Значение NaN в столбце «Состояние / включение» будет означать, что устройство не отвечает на эту конкретную команду (либо уже включено, либо введено несколько команд).

Я начал пытаться разобраться в этом и попал в кучу циклов for и множества логики if / else и подумал, что должен быть лучший способ.

Любая помощь приветствуется!

EDIT:

1 Ответ

1 голос
/ 15 февраля 2012

Я взял паузу, пробежал пару миль, затем сделал еще один удар, и это лучшее, что я придумал до сих пор.

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

Если кто-нибудь увидит какие-либо возможности для улучшения или логические дыры, дайте мне знать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...