Select random data from a matrix and replace it

7 visualizaciones (últimos 30 días)
stelios loizidis
stelios loizidis el 14 de Mayo de 2019
Comentada: Jos (10584) el 16 de Mayo de 2019
Hello,
I have the following problem: I have a matrix e.g
1 0 1 0 1
1 1 1 0 0
1 1 1 1 1
1 1 0 0 1
and I try to do this: When the sum of each column exceeds the threshold=4 some random "1" of the column that goes beyond the threshold become zero. How do I implement this in matlabThis can be done without using loops?I would be very grateful if someone helpend me

Respuesta aceptada

Andrei Bobrov
Andrei Bobrov el 14 de Mayo de 2019
Editada: Andrei Bobrov el 15 de Mayo de 2019
A = [1 0 1 0 1
1 1 1 0 0
0 0 0 0 0
1 1 1 1 1
1 1 0 0 1
0 0 0 0 0];
p = 4;
[ii,jj] = find(A);
jjj = accumarray(ii,jj,[size(A,1),1],@(x){x(randperm(numel(x),min(numel(x),p)))});
k = cellfun(@numel,jjj);
out = accumarray([repelem((1:numel(k))',k),cell2mat(jjj)],1,size(A));
  5 comentarios
Andrei Bobrov
Andrei Bobrov el 15 de Mayo de 2019
I'm fixed.
stelios loizidis
stelios loizidis el 15 de Mayo de 2019
It works!!!Thank you very much!!!!!!

Iniciar sesión para comentar.

Más respuestas (2)

Jos (10584)
Jos (10584) el 15 de Mayo de 2019
Editada: Jos (10584) el 15 de Mayo de 2019
Here is another, indexing, approach:
A = randi(2, 6, 8)-1 % random 0/1 array
M = 3 % max number of 1's per column
szA = size(A) ;
B = zeros(szA) ;
tf = A == 0 ;
[~, P] = sort(rand(szA)) ; % randperm for matrix along columns
P(tf) = 0 ;
[~, r] = maxk(P, M) ; % rows with M highest values in P (including 0's) per column
i = r + szA(1)*(0:szA(2)-1) ; % convert to linear indices
B(i) = 1 ; % B contains M 1's per column
B(tf) = 0 % reset those that were 0 in A -> only maximally M 1's per column remain
  2 comentarios
stelios loizidis
stelios loizidis el 16 de Mayo de 2019
Works what I suggest and thank you very much!!!
I just have the following question: Once matrix B is created with
0 's and 1 's how it stays stable without changing put 0 's and 1's every time i run the code?
Jos (10584)
Jos (10584) el 16 de Mayo de 2019
I don't get it. Why not simply run the code only once for a given matrix A?

Iniciar sesión para comentar.


Jan
Jan el 16 de Mayo de 2019
Editada: Jan el 16 de Mayo de 2019
A logical mask is much simpler than handling the indices:
A = randi([0,1], 8, 8); % Test data
p = 4;
mask = (cumsum(A, 1) > p) & A;
A(mask) = randi([0,1], nnz(mask), 1);
This replaces 1s in each column by a 0 with a probability of 50%, but leaves the first p ones untouched.
But if you want to change any 1s without keeping the first p 1s of each column:
mask = (sum(A, 1) > p) & A; % cumsum -> sum, auto-expand: >= R2016b
A(mask) = randi([0,1], nnz(mask), 1);
If you want to replace the 1s in the columns with more than p 1s with another probability:
A(mask) = rand(nnz(mask), 1) > 0.85;
  3 comentarios
Jan
Jan el 16 de Mayo de 2019
Editada: Jan el 16 de Mayo de 2019
@Jos: A maximum number of ones? Do you mean a minimum number of ones? I admit, I'm more and more confused.
Jos (10584)
Jos (10584) el 16 de Mayo de 2019
From the OP: "When the sum of each column exceeds the threshold=4 some random "1" of the column that goes beyond the threshold become zero."
If I now read it again, just a single one in such a column should be set to 0 then? ...

Iniciar sesión para comentar.

Categorías

Más información sobre Numeric Types en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

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

Start Hunting!

Translated by