Replicate elements from an array into a different array in Matlab

心已入冬 提交于 2019-12-24 23:33:00

问题


In Matlab I have an array "latencies" (size 1x11) and a cell array "Latencies_ms" (size 1x298). latencies is a smaller part of Latencies_ms, i.e. the values in latencies exist within Latencies_ms. I want to be able to find each value in latencies inside Latencies_ms and then add 1000 to that value and repeat this 8 times inside Latencies_ms.

So for example,

latencies = [62626  176578  284690  397708  503278  614724  722466] 

and (a small sample of Latencies_ms)

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

I want the output to be

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

As a starting point I decided to see if I could just replicate each element without adding 1000 and I have used the following code with repmat:

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

where I match the elements of latencies with Latencies_ms and then use repmat however using it like this inserts the entire latencies array at the correct locations rather than repeating the elements.

Then if I try using a for-loop like this:

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

it repeats just the last element of latencies so its correctly doing the replication but not of the correct elements.

I'm not too proficient with arrayfun and I think its whole point is to avoid using for-loops so I'm sure this isn't the correct way anyway but I feel like I'm almost there... Does anyone know what I am missing???

I don't have to use arrayfun, I tried to do this using for-loops but it got a bit messy but there isn't a restriction on using just arrayfun I just want to get to the correct output!


回答1:


Here is a loopless way:

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

The factor 9 in 2nd and 4th line is there since the matched element is to be kept once and repeated 8 times with increments (total = 9 times). The second line can be written with implicit expansion in ≥ R2016b as:

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

arrayfun is a one-line wrapper for a loop. It is still a loop. But loops have been significantly improved in newer versions (starting from R2015b) and sometimes their performance even surpass the vectorised code. So no need to avoid an easy loop that you can understand for complicated vectorisation unless it's a bottle-neck.



来源:https://stackoverflow.com/questions/51009288/replicate-elements-from-an-array-into-a-different-array-in-matlab

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!