一個可能的解決方案:
Label = randi([1 6], [100 1]); %# random Nx1 vector of labels
m = [2 3 1 0 1 2]; %# number of records to sample from each category
LabelIndicatorMatrix = false(size(Label)); %# marks selected records
uniqL = unique(Label); %# unique labels: 1,2,3,4,5,6
for i=1:numel(uniqL)
idx = find(Label == uniqL(i)); %# indices where label==k
ord = randperm(length(idx)); %# random permutation
ord = ord(1:min(m(i),end)); %# pick first m_k
LabelIndicatorMatrix(idx(ord)) = true; %# mark them as selected
end
爲了確保我們滿足要求,我們檢查:
>> sum(LabelIndicatorMatrix) == sum(m)
ans =
1
這是我在向量化的解決方案的嘗試:
Label = randi([1 6], [100 1]); %# random Nx1 vector of labels
m = [2 3 1 0 1 2]; %# number of records to sample from each category
%# some helper functions
firstN = @(V,n) V(1:min(n,end)); %# first n elements from vector
pickN = @(V,n) firstN(V(randperm(length(V))), n); %# pick n elements from vector
%# randomly sample labels, and get indices
idx = bsxfun(@eq, Label, unique(Label)'); %'# idx(:,k) indicates where label==k
[r c] = find(idx); %# row/column indices
idx = arrayfun(@(k) pickN(r(c==k),m(k)), 1:size(idx,2), ...
'UniformOutput',false); %# sample m(k) from labels==k
%# mark selected records
LabelIndicatorMatrix = false(size(Label));
LabelIndicatorMatrix(vertcat(idx{:})) = true;
%# check results are correct
assert(sum(LabelIndicatorMatrix)==sum(m))