Как сбалансировать уникальные значения в массиве Matlab - PullRequest
1 голос
/ 19 июня 2020

У меня есть вектор

Y = [1 1 0 0 0 1 1 0 1 0 1 1 1 0 0 0 1 1 0 0 0 0 1 0 1 0 1 0 1 1 1 0 0 0 1 0 0 0]

1 встречается 17 раз

0 встречается 21 раз

Как я могу случайным образом удалить нули, чтобы оба значения имели равные количества, например 1 (17 раз) и 0 (17 раз)?

Это также должно работать на гораздо большей матрице.

Ответы [ 2 ]

3 голосов
/ 19 июня 2020

Если данные могут иметь только два значения

Предполагаются значения 0 и 1. Наиболее частое значение удаляется случайным образом для выравнивания их счетчиков:

Y = [1 1 0 0 0 1 1 0 1 0 1 1 1 0 0 0 1 1 0 0 0 0 1 0 1 0 1 0 1 1 1 0 0 0 1 0 0 0]; % data
ind0 = find(Y==0); % indices of zeros
ind1 = find(Y==1); % indices of ones
t(1,1:numel(ind0)) = ind0(randperm(numel(ind0))); % random permutation of indices of zeros
t(2,1:numel(ind1)) = ind1(randperm(numel(ind1))); % same for ones. Pads shorter row with 0
t = t(:, all(t,1)); % keep only columns that don't have padding
result = Y(sort(t(:))); % linearize, sort and use those indices into the data

Обобщение для более чем двух значений

Значения произвольные. Все значения, кроме наименее распространенного, случайным образом удаляются, чтобы уравнять их количество:

Y = [0 1 2 0 2 1 1 2 0 2 1 2 2 0 0]; % data
vals = [0 1 2]; % or use vals = unique(Y), but absent values will not be detected
t = [];
for k = 1:numel(vals) % loop over values
    ind_k = find(Y==vals(k));
    t(k, 1:numel(ind_k)) = ind_k(randperm(numel(ind_k)));
end
t = t(:, all(t,1));
result = Y(sort(t(:)));
3 голосов
/ 19 июня 2020

Начиная с вашего примера

Y = [1 1 0 0 0 1 1 0 1 0 1 1 1 0 0 0 1 1 0 0 0 0 1 0 1 0 1 0 1 1 1 0 0 0 1 0 0 0]

Вы можете сделать следующее:

% Get the indices of the value which is more common (`0` here)
zeroIdx = find(~Y); % equivalent to find(Y==0)
% Get random indices to remove
remIdx = randperm(nnz(~Y), nnz(~Y) - nnz(Y));
% Remove elements
Y(zeroIdx(remIdx)) = [];

Вы можете объединить последние две строки, но я думаю, что это будет менее понятно.

Строка randperm выбирает правильное количество элементов для удаления из случайных индексов от 1 до количества нулей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...