Създаване на матрица от индекси на максимални стойности в MATLAB

Използвайки MATLAB, имам масив от стойности с размер 8 реда x N колони. Трябва да създам матрица със същия размер, която отчита максималните стойности във всяка колона и поставя 1 в клетката, която съдържа максимална стойност, и 0 другаде.

Малък пример. Да предположим, че имаме масив от стойности D:

    D =
      0.0088358   0.0040346   0.40276     0.0053221
      0.017503    0.011966    0.015095    0.017383
      0.14337     0.38608     0.16509     0.15763
      0.27546     0.25433     0.2764      0.28442
      0.01629     0.0060465   0.0082339   0.0099775
      0.034521    0.01196     0.016289    0.021012
      0.12632     0.13339     0.11113     0.10288
      0.3777      0.19219     0.005005    0.40137

Тогава изходната матрица за такава матрица D ще бъде:

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

Има ли начин да го направите, без да хванете вектор от индекси от функцията max и след това да ги поставите на правилното място, като използвате цикъл for?


person Gacek    schedule 17.01.2010    source източник
comment
Можете да направите това в Python за нула време;)   -  person Hamish Grubijan    schedule 17.01.2010
comment
за съжаление трябва да използвам Matlab :)   -  person Gacek    schedule 17.01.2010
comment
От любопитство, как бихте искали да се справите със случая, когато има две или повече стойности, които са равни на максимума в колона?   -  person gnovice    schedule 17.01.2010
comment
Винаги трябва да има само едно 1 във всяка колона. Тази матрица D съдържа коефициенти на достоверност за някои конкурентни алгоритми и винаги трябва да има само един избран. Така че, ако има две или повече еднакви стойности, алгоритъмът винаги трябва да избира само една, без значение коя.   -  person Gacek    schedule 18.01.2010


Отговори (3)


Вероятно има по-добри начини да го направите, първият ми подход е:

D          = rand(8,4)

[val, sub] = max(D)    
ind        = sub2ind( size(D), sub, 1:4 )

res        = false( size(D) )
res( ind ) = true
person Mikhail    schedule 17.01.2010
comment
Работи доста като чар. Благодаря, Михаил! - person Gacek; 17.01.2010
comment
+1: Това е решението за случая, когато просто искате да намерите първото появяване на максимална стойност в колона. За намиране на всяка стойност, равна на максимума за всяка колона, решението на Amro е най-доброто. - person gnovice; 18.01.2010
comment
Виждам. За щастие винаги има само една максимална стойност и всъщност трябва да има само едно 1 във всяка колона. В друг случай алгоритъмът ми ще се срине. И така, малко случайно, това решение е най-доброто за моя случай - person Gacek; 18.01.2010

Отговор от един ред:

M = D==repmat(max(D),size(D,1),1)

или по-елегантно:

M = bsxfun(@eq, D, max(D))

Актуализация:

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

M( cumsum(M)>1 ) = false

което ще гарантира, че в случай на множество максимуми само първият, който се появи, има съответен такъв в изходната матрица (това е еквивалентно на поведението на върнатия индекс на функцията max()).

person Amro    schedule 17.01.2010
comment

Няма нищо подобно на филтърния контейнер, той е включен в контейнера на сървлета.

- person gnovice; 18.01.2010
comment
Предполагам, че OP сега може да избере адекватното решение.. добра уловка обаче (истината е, че просто мислех да напиша по-кратък код!) - person Amro; 18.01.2010
comment
Благодаря, забравих за случая на повече от една максимална стойност. Всъщност е почти невъзможно да се появи в моя алгоритъм, но... Е, както коментирах в други отговори, винаги трябва да избирам само една стойност, така че другото решение е по-добро. - person Gacek; 18.01.2010

Написах разширение на оригиналния проблем, което може да обработва произволен многоизмерен масив и да търси максимум по всяко определено измерение.

Използвах го за решаване на равновесието на Наш в теорията на игрите. Надяваме се, че други ще го намерят за полезно.

A = rand([3 3 2]);
i = 1; % specify the dimension of A through which we find the maximum

% the following codes find the maximum number of each column of A
% and create a matrix M of the same size with A
% which puts 1 in the cell that contains maximum value, and 0 elsewhere.

[Amax pos] = max(A, [], i);
% pos is a now 1x3x3 matrix (the ith dimension is "shrinked" by the max function)

sub = cell(1, ndims(A));
[sub{:}] = ind2sub(size(pos), (1:length(pos(:)))');
sub{i} = pos(:);

ind = sub2ind(size(A), sub{:});
M = false(size(A));
M(ind) = true;

Пример:

A(:,:,1) =

0.0292    0.4886    0.4588
0.9289    0.5785    0.9631
0.7303    0.2373    0.5468

A(:,:,2) =

0.5211    0.6241    0.3674
0.2316    0.6791    0.9880
0.4889    0.3955    0.0377

M(:,:,1) =

 0     0     0
 1     1     1
 0     0     0

M(:,:,2) =

 1     0     0
 0     1     1
 0     0     0
person desktable    schedule 05.06.2010
comment
Пример: A(:,:,1) = 0,0292 0,4886 0,4588 0,9289 0,5785 0,9631 0,7303 0,2373 0,5468 A(:,:,2) = 0,5211 0,6241 0,3674 0,2316 0,6791 0,9 880 0,4889 0,3955 0,0377 M(:,:,1) = 0 0 0 1 1 1 0 0 0 M(:,:,2) = 1 0 0 0 1 1 0 0 0 - person desktable; 06.06.2010