How can I select a random element from each column of an array, ignoring zeros

1 view (last 30 days)
I have an array of m*n elements, some of them zeros, for example:
A = [1 0 2 3; 0 1 5 6; 0 0 0 4]
I would like to draw randomly, one single non- zero element from each column. one such vector could be:
[1 1 2 6] for example.
I have tried replacing zeros with nan's and using the datasample function to do this, but it does not ignore nan's.
is there a simple way to do this without a loop?
thanks

Accepted Answer

Bruno Luong
Bruno Luong on 1 Oct 2018
B = A;
B(B==0) = NaN;
B = sort(B,1);
[~,rlast] = max(B,[],1);
rrand = ceil(rand(size(rlast)).*rlast);
rval = B(sub2ind(size(B),rrand,1:size(B,2)))
  5 Comments
Bruno Luong
Bruno Luong on 2 Oct 2018
Edited: Bruno Luong on 2 Oct 2018
Something I don't get it.
According to this wiki page , MT algo generates numbers MT in [0, 2^w−1], so the discrete sample are even (w=53 according to you).
If
rand = MT/2^53
then rand() generates number in [0,1), this is contradict with the doc and rand, which states the number are in open interval (0,1).
But let assumes RAND just simple divide MT, then to have exactly half probability you should call
r01 = rand < 0.5
If however RAND discard 0 (by rejection) then the number of discrete samples is odd, then to have non bias you have to do
r = rand;
while r==0.5
r = rand;
end
r01 = r < 0.5

Sign in to comment.

More Answers (1)

Walter Roberson
Walter Roberson on 1 Oct 2018
is there a simple way to do this without a loop?
No. There are ways to do it with disguised loops, but I would not call them simple.
Index = @(V,K) V(K)
OneOfOneCol = @(V) Index(V(find(V)), randi(nnz(V)) );
OneOfEachCol = @(M) arrayfun(@(COL) OneOfOneCol(M(:,COL)), 1:size(M,2));
then
OneOfEachCol(A)
This code will fail if there is a column that has only zeros.
  3 Comments
Walter Roberson
Walter Roberson on 1 Oct 2018
Is it a major cause?
I am not sure what you are asking?
If you are asking whether a for loop is always slower then vectorization, the answer is NO, there are situations where for loops can be faster than vectorization. Even when vectorization can be used to solve a situation, it is common that it involves scanning an array multiple times, or involves temporary variables as large as the original variables.

Sign in to comment.

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!