Реплицируйте элементы из массива в другой массив в Matlab - PullRequest
0 голосов
/ 24 июня 2018

В Matlab у меня есть массив "latencies" (размер 1x11) и массив ячеек "Latencies_ms" (размер 1x298). latencies - это меньшая часть Latencies_ms, то есть значения в latencies существуют в Latencies_ms. Я хочу иметь возможность найти каждое значение в latencies внутри Latencies_ms, а затем добавить 1000 к этому значению и повторить это 8 раз внутри Latencies_ms.

Так, например,

latencies = [62626  176578  284690  397708  503278  614724  722466] 

и (небольшой образец Latencies_ms)

Latencies_ms = {3458, 62626, 123456, 7891011, 121341, 222112, 176578}

Я хочу, чтобы вывод был

out = {3458, 62626, 63626,  64626,  65626,  66626,  67626,  68626,  69626,  70626, 123456, 7891011, 121341, 222112, 176578, 177578, 178578, 179578, 180578, 181578, 182578, 183578, 184578,}

В качестве отправной точки я решил посмотреть, могу ли я просто скопировать каждый элемент без добавления 1000, и я использовал следующий код с repmat:

out = arrayfun( @(x,b)[x; repmat({latencies},8,1)],... 
Latencies_ms, ismember(cell2mat(Latencies_ms),latencies), 'uni', 0 );
out = vertcat(out4{:});

, где я сопоставляю элементы латентностей с Latencies_ms, а затем использую repmat, но, используя его таким образом, вставляю весь массив latencies в правильные места, а не повторяю элементы.

Тогда, если я попытаюсь использовать цикл for, как это:

for i=1:length(latencies)
   out = arrayfun( @(x,b)[x; repmat({latencies(i)},8,1)],... 
   Latencies_ms, ismember(cell2mat(Latencies_ms),latencies), 'uni', 0 );
   out = vertcat(out4{:});
end

он повторяет только последний элемент задержек, поэтому он правильно выполняет репликацию, но не правильных элементов.

Я не слишком опытен с arrayfun, и я думаю, что весь смысл в том, чтобы избегать использования циклов for, так что я уверен, что в любом случае это не правильный путь, но я чувствую, что я почти там .. Кто-нибудь знает, чего мне не хватает ???

Мне не нужно использовать arrayfun, я пытался сделать это с помощью for-loop, но это немного запутанно, но нет ограничений на использование только arrayfun. Я просто хочу получить правильный вывод!

1 Ответ

0 голосов
/ 24 июня 2018

Вот способ без петель:

ind = ismember([Latencies_ms{:}] , latencies);      %Indices of the values to be repeated
repvals = bsxfun(@plus, repmat([Latencies_ms{ind}], 9, 1).', 0:1000:8000); %Rep+increment
out = Latencies_ms;
out(ind) = mat2cell(repvals, ones(1, sum(ind)), 9); %Replacing with repeated+inc elements
out = [out{:}]; %Converting to comma-separated list and then concatenating horizontally

Коэффициент 9 во 2-й и 4-й строке присутствует, поскольку соответствующий элемент должен сохраняться один раз и повторяться 8 раз с приращениями (всего = 9 раз)).Вторая строка может быть записана с неявным расширением в ≥ R2016b как:

repvals  = repmat([Latencies_ms{ind}], 9, 1).' + (0:1000:8000);

arrayfun - это однострочная оболочка для цикла.Это все еще петля.Но циклы были значительно улучшены в более новых версиях (начиная с R2015b), и иногда их производительность даже превосходила векторизованный код.Поэтому нет необходимости избегать простой петли, которую вы можете понять для сложной векторизации, если только это не узкое место.

...