2015-01-18 2 views
1

У меня есть 2 вектора данных d1 = [1 2 1 3 4] и d2 = [3 1 2 1] и 2 ссылки howMany1= [3 2 2 1 2] и howMany2 = [2 1 2 2]. Элементы d1 и d2 следует повторять в соответствии с элементами howMany1 и howMany2: поэтому d1 (1), т.е. первый элемент d1 должен повторять 3 раза, d1 (2) должен повторять 2 раза и т. Д .. и конечный результат должен быть d1_repeated = [1 1 1 2 2 1 1 3 4 4] и d2_repeated = [3 3 1 2 2 1 1]Как сделать элементы нескольких векторов повторяющимися MATLAB?

Как я мог сделать это в MATLAB? Я просмотрел аналогичную запись, в которой повторяется один вектор, поэтому я попытался сделать то же самое и сделал цикл for. Вот мой код:

clear all 
close all 
clc 
% data 

d1 = [1 2 1 3 4]; 
d2 = [3 1 2 1]; 
howMany1 = [3 2 2 1 2]; % Determines how many times each index in IDX1 should be repeated. 
howMany2 = [2 1 2 2]; 
d = {d1 d2} 
howMany = {howMany1 howMany2} 
Anew = cell(1,2) 
for k = 1:2 % 2 data vectors  
Anew{1,k} = arrayfun(@(x) repmat(d{k}(x), howMany{k}(x), 1), 1:numel(d{k}), 'uni', 0); 
Anew = vertcat(Anew{:}); 

end 

, но я получаю следующее сообщение об ошибке:

Error using vertcat 

Dimensions of matrices being concatenated are not consistent. 

Затем я попытался изменить верт кошку horzcat, но я получаю повторы как группа двойников:

Anew = 

    Columns 1 through 7 

    [3x1 double] [2x1 double] [1] [2x1 double] [2x1 double] [2x1 double] [3] 

    Column 8 

    [2x1 double] 

Im интересно, в чем проблема? Спасибо, что нашли время.

+0

В дополнение к дубликату в флагове см. Также http://stackoverflow.com/q/1975772/2778484. – chappjc

ответ

4

Это может быть сделано путем объединения IsMember и cumsum:

d1(cumsum(ismember(1:sum(howMany1),cumsum([1 howMany1])))) 

Разбивка:

Сравнить 1:sum(howMany1) с кумулятивной суммы howMany1. Это вектор с 1 и 0, который показывает положение, где должно начинаться следующее значение из d1.

ismember(1:sum(howMany1),cumsum([1 howMany1])) 
ans = 
    1  0  0  1  0  1  0  1  1  0 

Совокупная сумма это дает вектор, который выглядит как:

cumsum(ismember(1:sum(howMany1),cumsum([1 howMany1]))) 
ans = 
    1  1  1  2  2  3  3  4  5  5 

Теперь, это может быть использовано в качестве индексов для d1 при создании d1_repeated.

d1(cumsum(ismember(1:sum(howMany1),cumsum([1 howMany1])))) 
ans = 
    1  1  1  2  2  1  1  3  4  4 
+2

Несмотря на то, что это дублированный вопрос, это новый ответ. Умное использование 'ismember'! +1 – chappjc

Смежные вопросы