Median() ignoring zeros
36 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Is there any cheap way to get the median of the columns of the non-zero elements of an unsorted NxN matrix? Please note that B = median(A~=0) doesn't work for a matrix. Thanks!
2 Kommentare
bama Srinivasan
am 23 Nov. 2016
Bearbeitet: Walter Roberson
am 23 Nov. 2016
I suppose have a matrix named as 'a', which contains both zero and non zero entries. To get the median ignoring zeros, the following two lines will be sufficient.
b=find(a~=0);% get the locations of nonzero.
median(a(b))%median of the non zero entries
Walter Roberson
am 23 Nov. 2016
bama Srinivasan, that indexing a(b) would create a vector, and then median() of the entire vector at once would be taken. The question had to do with getting the medians on a column-by-column basis with 0 being ignored.
Antworten (3)
Rickard Shen
am 12 Sep. 2012
You can use NANMEDIAN, it works in the same way as MEDIAN, but ignores NaN-values.
---------------------------------------------------------
Example:
A = [
1 3 4 2 4 3 6
2 6 0 9 4 5 2
7 8 0 2 3 0 8
0 0 4 7 6 5 9
0 0 2 7 4 3 1
];
A(A==0) = NaN;
B = nanmedian(A);
A(isnan(A)) = 0; %If you need to get the zeros back
--> B = 2 6 4 7 4 4 6
---------------------------------------------------------
Performance test with a very large matrix with lots of 0s:
Elapsed time is 4.165831 seconds. <-- using nanmedian
Elapsed time is 12.898844 seconds. <-- using arrayfun
Elapsed time is 9.930400 seconds. <-- using for-loop
2 Kommentare
Albert
am 22 Nov. 2016
Hi, Rickard Shen
Could you give a better answer to its variation?
What if A is a large size sparse matrix, how are you going to find the median of each row/col array in sparse matrix A?
Please note that A is a very large size sparse matrix, and syntax 'A(A==0) = NaN;' is not practicable anymore. It takes forever to convert zeros into NaN in a very large size sparse matrix.
Meanwhile, I don't want to use loop to do this job.
Also I don't understand why MATLAB doesn't add a nonzero flag in the median function. However, there is a nan flag in median function.
Please help further.
Greatly appreciate it.
Image Analyst
am 22 Nov. 2016
A flag to eliminate zeros is just not very general. What's special about zero? To make it more general, then you'd have to have an input to eliminate ANY value in the matrix. But then, what's so special about one value being eliminated? Nothing, so to make it more general you'd have to take in a variable that is a list of all values that you want it to ignore. However if the numbers are not integers, now we have a special situation as explained in the FAQ http://matlab.wikia.com/wiki/FAQ#Why_is_0.3_-_0.2_-_0.1_.28or_similar.29_not_equal_to_zero.3F So now you'd have to supply some tolerance as input in addition to the list of numbers to exclude. So now, it's rapidly becoming much more complicated than a simple median function. You might as well just pass your array through setdiff(). And who knows, you might have other criteria, like ignore all negative numbers, or ignore all non-integers, or whatever. Since putting in all that would make it horribly slow and complicated, it just leaves all that stuff for you to do before you call median().
Fangjun Jiang
am 2 Jan. 2012
You probably need to do a for-loop.
Col=size(A,2);
B=zeros(1,Col);
for k=1:Col
B(k)=median(A(A(:,k)~=0,k));
end
0 Kommentare
Dr. Seis
am 2 Jan. 2012
Or without for-loop:
B = arrayfun(@(k)median(A(A(:,k)~=0,k)),1:size(A,2));
1 Kommentar
Rickard Shen
am 12 Sep. 2012
Bearbeitet: Rickard Shen
am 12 Sep. 2012
It seems that Matlab has to run a loop in the background anyways, so the performance I got with ARRAYFUN was actually lower than with my own for-loop. It is nonetheless a very neat and elegant row of code you wrote!
Elapsed time is 12.906827 seconds. <-- arrayfun
Elapsed time is 9.956609 seconds. <-- my for-loop
Siehe auch
Kategorien
Mehr zu Resizing and Reshaping Matrices finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!