Matlab Найти-Заменить в матрице Single Liner? - PullRequest
1 голос
/ 09 марта 2012

Скажем, у меня есть следующая матрица:

1 0 1 1 0 0
0 0 1 0 1 0
1 1 1 0 0 1
0 1 1 0 0 1
1 1 1 1 1 0

Я хочу преобразовать ее в другой формат, где я заменяю каждую 1 в каждой строке на индекс ее столбца, чтобы он стал следующим:

1 0 3 4 0 0
0 0 3 0 5 0
1 2 3 0 0 6
0 2 3 0 0 6
1 2 3 4 5 0

Я могу сделать это "тупым" способом:

[H, W] = size(a);
for i = 1:H
    for j = 1:W
        if(a(i, j) == 1) 
            a(i, j) = j;
        end
    end
end

Но, безусловно, должен быть способ сделать это одной строкой (возможно, с помощью функции 'find'),кто-нибудь знает как?

Ответы [ 4 ]

3 голосов
/ 09 марта 2012

у вас есть матрица a

[r,c]=ind2sub(size(a),find(a));
a(find(a))=c;

Изменить: это выполнимо в одну строку, так как это важно для вас:

[r,a(find(a))]=ind2sub(size(a),find(a));
3 голосов
/ 09 марта 2012

Это не супер общий, но делает то, что вы хотите.find возвращает индексы в одномерную версию данных, поэтому нам нужно сделать небольшую арифметику, чтобы получить двумерные версии:

a(a == 1) = floor((find(a == 1) - 1) / size(a, 1)) + 1

Если вы хотите вместо этого использовать индексы строк,Вы могли бы использовать

a(a == 1) = mod(find(a == 1) - 1, size(a, 1)) + 1

Если вы делали это с большой матрицей, вы можете сначала присвоить find(a == 1) временной переменной:

inds = find(a == 1)
a(inds) = floor((inds - 1) / size(a, 1)) + 1

(Обратите внимание, что индексация вa со списком индексов или с матрицей логических значений работает одинаково.)

Вы также можете просто использовать find(a), если знаете, что исходная матрица содержит только 0 и 1.

Обратите внимание, что это просто делает вручную в основном то, что делает ответ @ tmpearce .

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

Вы можете использовать meshgrid, чтобы сделать это:

[H, W] = size(a);
a = a.*meshgrid(1:H,1:W);
0 голосов
/ 09 марта 2012

Прошло много времени с тех пор, как я использовал matlab, поэтому я не смогу дать вам код из моей головы. Но вот как я бы это сделал:

Создайте вектор 1:colums, повторите его один раз для каждой строки, используя repmat, а затем умножьте это поэлементно на исходную матрицу.

Кроме того, поскольку циклы медленны в matlab, а матричные операции быстры, такой однострочный код, вероятно, будет намного быстрее, чем код, который вы сейчас имеете.

...