Obținerea indicelui valorii mediane în MATLAB (Programare, Matlab, Indexare, Mediană)

Gacek a intrebat.
a intrebat.

Atunci când se caută min sau max se poate obține indicele valorii găsite astfel:

[val, index] = max(some_array_of_values);

Cum se obține indicele valorii medii median valoare?

NOTĂ:
Da, știu ce este mediana și știu că uneori poate fi media a două valori de la mijloc. Ceea ce vreau să obțin este indicele valorii cea mai apropiată sau egală cu valoarea mediană.
Matricea de valori conține valori nesortate. Nu putem sorta această matrice – am nevoie de indicele din matricea originală. Dar, desigur, putem sorta o copie a acestuia. Nu există limitări datorate dimensiunii tabloului – acesta este relativ mic (aproximativ 100 de valori).

6 răspunsuri
Janne Peltola

Pentru seturile care includ mediana, puteți utiliza find și median.

 a = [1, 2, 3, 4, 5]
 find(a == median(a))

Pentru seturile care nu includ mediana lor, trebuie să deveniți isteți. Mai întâi găsim cel mai mic indice care este mai mare decât mediana și cel mai mare indice care este mai mic decât mediana. Aici, bineînțeles, presupun că setul este sortat. Acest lucru face totul mai ușor.

 b = [1, 2, 3, 4]
 (min(find(b>median(b))) + max(find(b<median(b)))) / 2

Ultima soluție ar trebui să funcționeze în ambele cazuri. Observați că indicele pentru o mediană inexistentă nu este deloc un indice propriu-zis și ar trebui să folosiți valoarea în consecință (pentru orice ați dori să faceți cu ea).

Comentarii

  • Setul nu este sortat. Dacă ar fi fost sortat, aș fi făcut-o de unul singur 🙂 –  > Por Gacek.
  • Nu puteți sorta setul? Atunci aș încerca mai întâi să caut mediana folosind find(b == median(b)) și verificând dacă length() == 0 (adică dacă mediana este inclusă în set). Dacă acesta este cazul, puteți obține pozițiile valorilor care depășesc mediana folosind min(find(b > median(b))) și max(find(b < median(b))). Ce altceva ați dori să găsiți? –  > Por Janne Peltola.
  • Mulțumesc pentru ajutor, bazându-mă pe răspunsul dvs. am găsit soluția pe cont propriu. Vă mulțumesc din nou! –  > Por Gacek.
Amro

Ideea este de a sorta vectorul și de a lua valoarea de mijloc. Pentru vectori de lungime pară, calculăm media celor două valori din mijloc.

Exemplu:

%# some random vector
%#x = rand(99,1);        %# odd-length
x = rand(100,1);         %# even-length

%# index/indices for median value
num = numel(x);
[~,ord] = sort(x);
idx = ord(floor(num/2)+(rem(num,2)==0):floor(num/2)+1);

%# median value
med = mean( x(idx) );

%# compare against MATLAB's function
median(x)

EDIT

Iată un exemplu de implementare a unei funcții:

function [med idx] = mymedian(x)
    %# MYMEDIAN
    %#
    %# Input:   x        vector
    %# Output:  med      median value
    %# Output:  idx      corresponding index
    %#
    %# Note: If vector has even length, idx contains two indices
    %# (their average is the median value)
    %#
    %# Example:
    %#    x = rand(100,1);
    %#    [med idx] = mymedian(x)
    %#    median(x)
    %#
    %# Example:
    %#    x = rand(99,1);
    %#    [med idx] = mymedian(x)
    %#    median(x)
    %#
    %# See also: median
    %#

    assert(isvector(x));
    [~,ord] = sort(x);
    num = numel(x);

    if rem(num,2)==0
        %# even
        idx = ord(floor(num/2):floor(num/2)+1);
        med = mean( x(idx) );
    else
        %# odd
        idx = ord(floor(num/2)+1);
        med = x(idx);
    end
end

Sparx

O modalitate de a aborda această problemă este de a scădea mediana și de a găsi minimul valorilor absolute ale vectorului rezultat:

[val, index] = min(abs(some_array_of_values - median(some_array_of_values)));

Ca rezultat, veți obține cea mai apropiată valoare de mediană.

Acest lucru ar trebui să funcționeze pentru a găsi orice indice al unei valori cel mai apropiat de o valoare_de_interes.

[val, index] = min(abs(some_array_of_values - value_of_interest));

Gacek

OK, am găsit o soluție pe cont propriu.

În primul rând, sortez valorile din vectorul meu D

S = sort(D)

Apoi caut primul element care este mai mare sau egal cu mediana

idS = find(S >= median(S),1)

acum pot obține valoarea exactă a acelui element și încerc să o găsesc în vectorul original:

idMed = find(D == S(idS))

Comentarii

  • Acesta nu este un răspuns la întrebare așa cum a fost formulată. Ați spus că matricea nu poate fi sortată. –  > Por John.
  • Vedeți răspunsul meu de mai jos, care evită sortarea. –  > Por John.
  • @John, iar eu nu sortez matricea. Acesta este lăsat intact. Sortez o matrice temporară, copiată S –  > Por Gacek.
  • @Gacek, de obicei, nu asta înseamnă „Nu putem sorta această matrice”. –  > Por nibot.
  • @John, probabil că ai dreptate. Și, probabil, dacă aveai îndoieli, ar trebui să întrebi ce înseamnă exact. Mi-am actualizat întrebarea pentru a o clarifica. Mulțumesc pentru că ați subliniat-o. –  > Por Gacek.
nibot

Ceea ce vreau să obțin este indicele de valoare cel mai apropiat sau egal cu valoarea mediană. Matricea de valori conține valori nesortate. Nu putem sorta acest array.

Căutați o metodă rapidă algoritm de selecție. Cel mai probabil, nu veți putea depăși performanța funcțiilor încorporate în Matlab, cum ar fi sort și median (care se pare că utilizează sort în mod intern) prin scrierea de cod în Matlab însuși, deoarece aceasta va implica bucle lente. În schimb, dacă aveți cu adevărat nevoie de ceva mai eficient decât aceste soluții, va trebui să vă implementați propriile soluții într-un limbaj compilat.

nth_element din schimbul de fișiere Mathworks include o interfață mex pentru funcția din biblioteca standard C++ std::nth_element și include o funcție specială fast_median funcție specială – acesta ar putea fi un bun exemplu de la care să porniți. Va trebui să o modificați pentru a ține evidența indicilor din matrice.

John

Din moment ce matricea nu poate fi sortată, (probabil pentru că este foarte mare), și pentru că întrebarea este prost pusă (ce trebuie făcut în cazul unui număr impar de elemente în matrice), faceți următoarele:

ixMedian = function(v)

if (mod(numel(v),2) == 1)
   vtemp = v(1:end-1);
else
   vtemp = v;
end

ixMedian = find(vtemp == median(vtemp))

În cazul unui număr impar de elemente, se returnează mediana. În cazul unui număr par de elemente, se returnează unul dintre cele 4 elemente cele mai apropiate de mediană. În cazul în care elementele sunt distribuite uniform și dacă există 2N elemente, cu probabilitatea 1/N, se returnează unul dintre cele 2 elemente cele mai apropiate de mediană.

Comentarii

  • De ce există două voturi împotrivă pentru acest lucru? Răspunde exact la întrebare, fără să sorteze nimic. –  > Por John.