Random Sampling of Repeated Numbers in an Array
2 Comments
Agree with Jan if you only save the value there's no difference; appears that what your problem is that it matters which one is selected as there's something unique about position, not just magnitude. If that isn't so, then there is no difference and may as well just use the results of unique as one seven itself is as good as another; only if which seven makes a difference.
Accepted Answer
More Answers (3)
B = unique(Q); while i < length(Q) [row col] = find(Q == B(i)); i = i + 1; end
This cannot work, because B is shorter than Q, when Q is not unique. i must be <= length(B).
I do not understand the purpose of the code. All elements with the same value are identical, so it does not matter which e.g. 7 you select.
[EDITED] Another solution using FEX: RunLength:
Q = [7 7 7 8 8 8 10 18 27 42 65 49 54 65 78 78 78 82 87 98 98 7 7]'; [B, N, Index] = RunLength(Q); Select = floor(Index + rand(size(N)) .* N) Value = Q(Select)
This considers the 2 different blocks of 7s separately. But if Q is sorted, this might be efficient also.
4 Comments
A rough speed test:
Q = sort(randi([1,1e4], 1e5, 1));
tic; for k = 1:100 [B, N, Index] = RunLength(Q); % Compiles C-Mex Select = floor(Index + rand(size(N)) .* N); Value = Q(Select); end toc
tic; for k = 1:100 [B, N, Index] = RunLength_M(Q); % Matlab version Select = floor(Index + rand(size(N)) .* N); Value = Q(Select); end toc
tic; for k = 1:100 cnt = hist(Q,unique(Q)); idx = arrayfun(@randi,cnt) + cumsum([0,cnt(1:end-1)]); Value = Q(idx); end toc
tic; for k = 1:100 cnt = hist(Q,unique(Q)); idx = floor(rand(size(cnt)) .* cnt) + cumsum([1,cnt(1:end-1)]); Value = Q(idx); end toc R2016b/64/Win7:
Elapsed time is 0.116764 seconds. % RunLength MEX Elapsed time is 0.203199 seconds. % RunLength Matlab Elapsed time is 4.921286 seconds. % arrayfun(@randi,cnt) Elapsed time is 0.868590 seconds. % floor(rand * cnt)
p=randperm(length(Q)); [~,I]=unique(Q(p)); RandomSelect=p(I), % Q(RandomSelect) is equal to unique(Q)
1 Comment
On the assumption made in above comment...
>> [B,ia]=unique(Q); >> isMult3=(NCount==3); >> arrayfun(@(x) randperm(x,1),Ncount(isMult3)) % random index into matching groups ans = 1 3 2 >>
Now, fix up to get the index to the original location --
>> ix3=arrayfun(@(x) randperm(x,1),Ncount(isMult))+ia(find(Ncount==3))-1
ix3 =
1
5
15
>> Q(ix3)
Q =
7
8
78
>> Categories
Find more on Performance and Memory 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!