повторять значения в строке «N» количество раз, а затем увеличивать значения - Matlab (варьируется N) - PullRequest
2 голосов
/ 27 марта 2012

У меня есть матрица:

mat = [  2009 3 ;
         2010 2 ] ;

Мне нужно повторить Col1 согласно Col2. Решение на Повторение копий элементов массива: полезно декодирование длины прогона в MATLAB . Тем не менее, моя главная проблема состоит в том, чтобы затем увеличивать годы в соответствии с:

Ansmat = [  2009 3
            2010 3
            2011 3
            2010 2
            2011 2 ] ;

Я хочу избежать петли for здесь. Спасибо за вашу помощь! Это было бы очень полезно!

Ответы [ 3 ]

2 голосов
/ 27 марта 2012

Вы можете сначала скопировать свою матрицу, используя мой векторизованный ответ на предыдущий вопрос :

>> mat = [2009 3; 2010 2];
>> index = zeros(1, sum(mat(:, 2)));
>> index([1; cumsum(mat(1:end-1, 2))+1]) = 1;
>> Ansmat = mat(cumsum(index), :)

Ansmat =

        2009           3
        2009           3
        2009           3
        2010           2
        2010           2

Далее, вы можете создать вектор смещений столбцов для добавления к датам впервый столбецВот как вы можете сделать это векторизованным способом.

>> offset = ones(size(Ansmat, 1), 1);
>> offset([1; cumsum(mat(1:end-1, 2))+1]) = [0; 1-mat(1:end-1, 2)];
>> Ansmat(:, 1) = Ansmat(:, 1)+cumsum(offset)

Ansmat =

        2009           3
        2010           3
        2011           3
        2010           2
        2011           2
0 голосов
/ 27 марта 2012
incr = (0 : max(mat(:, 2)))';
incr = [incr, 0 * incr];
Ansmat = [];
for k = 1 : size(mat, 1)
    Ansmat = cat(1, Ansmat, repmat(mat(k, :), mat(k, 2), 1) + incr(1 : mat(k, 2), :));
end

Но если ожидаемый размер матрицы Ansmat велик, первое решение GummiV будет быстрее.

0 голосов
/ 27 марта 2012

Я не уверен, есть ли способ сделать это без цикла, так как это довольно непонятная операция, которую мы выполняем.Если я правильно понимаю ваш алгоритм, вот два метода, которые используют один цикл for:

B = zeros(sum(A(:,2)), 2);
counter = 1;
for i = 1:size(A,2)
    n = A(i,2);
    B(counter:counter+n-1,1) = A(i,1)+(0:n-1)';
    B(counter:counter+n-1,2) = n;
    counter = counter+n;
end

Вы можете покончить с предварительным распределением.Если переменная counter сбивает с толку, вы можете проверить эту переменную, которая добавляет матрицу B к каждой итерации, но вместо этого требуется начальный регистр.

n = A(1,2);
B = [A(1,1)+(0:n-1)', n*ones(n,1)];
for i = 2:size(A,2)
    n = A(i,2);
    B = [B; A(i,1)+(0:n-1)', n*ones(n,1)];
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...