Select random data from a matrix and replace it

2 vues (au cours des 30 derniers jours)
stelios loizidis
stelios loizidis le 14 Mai 2019
Commenté : Jos (10584) le 16 Mai 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

Réponse acceptée

Andrei Bobrov
Andrei Bobrov le 14 Mai 2019
Modifié(e) : Andrei Bobrov le 15 Mai 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 commentaires
Andrei Bobrov
Andrei Bobrov le 15 Mai 2019
I'm fixed.
stelios loizidis
stelios loizidis le 15 Mai 2019
It works!!!Thank you very much!!!!!!

Connectez-vous pour commenter.

Plus de réponses (2)

Jos (10584)
Jos (10584) le 15 Mai 2019
Modifié(e) : Jos (10584) le 15 Mai 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 commentaires
stelios loizidis
stelios loizidis le 16 Mai 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) le 16 Mai 2019
I don't get it. Why not simply run the code only once for a given matrix A?

Connectez-vous pour commenter.


Jan
Jan le 16 Mai 2019
Modifié(e) : Jan le 16 Mai 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 commentaires
Jan
Jan le 16 Mai 2019
Modifié(e) : Jan le 16 Mai 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) le 16 Mai 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? ...

Connectez-vous pour commenter.

Catégories

En savoir plus sur Data Preprocessing dans Help Center et File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!

Translated by