## Select random data from a matrix and replace it

stelios loizidis

### stelios loizidis (view profile)

さんによって質問されました 2019 年 5 月 14 日

### Jos (10584) (view profile)

さんによって コメントされました 2019 年 5 月 16 日
Andrei Bobrov

### Andrei Bobrov (view profile)

さんの 回答が採用されました
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

#### 0 件のコメント

サインイン to comment.

## 3 件の回答

2019 年 5 月 14 日

### Andrei Bobrov (view profile)

2019 年 5 月 15 日
採用された回答

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));

stelios loizidis

### stelios loizidis (view profile)

2019 年 5 月 14 日
The matrix A that I mention is a matrix 840X1145 and contains "1" and "0" and I tested the above solution the new matrix resulting i.e the matrix out has dimensions 840X1140. How to solve this problem because the matrix out it should also have dimensions of 840X1145 so I can make some other calculations.
Andrei Bobrov

2019 年 5 月 15 日
I'm fixed.
stelios loizidis

### stelios loizidis (view profile)

2019 年 5 月 15 日
It works!!!Thank you very much!!!!!!

サインイン to comment.

2019 年 5 月 15 日

### Jos (10584) (view profile)

2019 年 5 月 15 日

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

stelios loizidis

### stelios loizidis (view profile)

2019 年 5 月 16 日
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) (view profile)

2019 年 5 月 16 日
I don't get it. Why not simply run the code only once for a given matrix A?

サインイン to comment.

2019 年 5 月 16 日

### Jan (view profile)

2019 年 5 月 16 日

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;
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
If you want to replace the 1s in the columns with more than p 1s with another probability:

Jos (10584)

### Jos (10584) (view profile)

2019 年 5 月 16 日
I assumed that the OP wanted to leave a maximum number (M) of ones in each column. If there are more than M ones in a column, a random selection of those should be set to 0, so M ones remain.
Jan

### Jan (view profile)

2019 年 5 月 16 日
@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) (view profile)

2019 年 5 月 16 日
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? ...

サインイン to comment.

Translated by