Median() ignoring zeros
34 次查看(过去 30 天)
显示 更早的评论
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 个评论
bama Srinivasan
2016-11-23
编辑:Walter Roberson
2016-11-23
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
2016-11-23
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.
回答(3 个)
Rickard Shen
2012-9-12
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 个评论
Albert
2016-11-22
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
2016-11-22
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
2012-1-2
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 个评论
Dr. Seis
2012-1-2
Or without for-loop:
B = arrayfun(@(k)median(A(A(:,k)~=0,k)),1:size(A,2));
1 个评论
Rickard Shen
2012-9-12
编辑:Rickard Shen
2012-9-12
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
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Resizing and Reshaping Matrices 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!