596 views (last 30 days)

I have a very large matrix of ones and zeros X. I would like to replace all the ones in the first column with a value, and all the zeros in the same column with a different value. I would like to do the same for all of the columns in my matrix. What I've tried so far is

x(x(:,1)>0) = .75;

x(x(:,2)>.0) = .66;

x(x(:,3)>0) = .95;

x(x(:,1)<1) =.25;

x(x(:,2)<1) =.34;

x(x(:,3)<1) =.05;

However the code is replacing the ones (not the zeros) in the first column only, and not doing it correctly at that.

How can I fix this?

James Tursa
on 24 Sep 2018

Edited: James Tursa
on 24 Sep 2018

You are inadvertently using linear indexing because you don't supply the 2nd index. Change your code to:

x(x(:,1)>0,1) = .75;

x(x(:,2)>0,2) = .66;

x(x(:,3)>0,3) = .95;

x(x(:,1)<1,1) =.25; % <-- No ... see correction from Nicole below

x(x(:,2)<1,2) =.34;

x(x(:,3)<1,3) =.05;

Or, another way:

v = [0.75 0.66 0.95];

x(:,1:3) = bsxfun(@times,x(:,1:3),v) + bsxfun(@times,1-x(:,1:3),1-v);

Or if you have a later version of MATLAB

x(:,1:3) = x(:,1:3).*v + (1-x(:,1:3)).*(1-v);

And if your matrix only has three columns,

x = bsxfun(@times,x,v) + bsxfun(@times,1-x,1-v);

or

x = x.*v + (1-x).*(1-v);

James Tursa
on 24 Sep 2018

Nicole Peltier
on 24 Sep 2018

The output is:

x =

0.2500 0.3400 0.0500

0.2500 0.3400 0.0500

0.2500 0.3400 0.0500

0.2500 0.3400 0.0500

...

because once the first three lines run, every item in x is less than 1.

James Tursa
on 24 Sep 2018

Ah, yes! Good catch! (Shame on me for using a temporary variable in my testing and jumping to the vectorized code too quickly ...)

And, to make the whole algorithm more robust, it should be noted that even with the ==0 correction it will not work properly if one of the values on the rhs is 0. So, best either to use temporary variables to save the logical locations or just use vectorized code to begin with.

Sign in to comment.

aepound
on 24 Sep 2018

In your example, you are indexing into a 2D x matrix x( ) with the values of the column x(:,3) that are > 0. You probably mean to do something more like this:

x(x(:,1),1) = .75;

x(x(:,2),2) = .66;

That being said, if the matrix is binary (i.e. 0s and 1s), then I would try to take advantage of logical indexing. The idea is that your matrix is already logical, and the things that you want to replace can be added in using that.

The difficulty lies in teasing out what shape your values need to be in that you want to put into the matrix. Because you are working column by column, it isn't the worst thing to come up with. I've included a small demo below that you should be able to try out and modify to work for you. Of note, if you haven't worked with logical matrices/vectors before: You can use the "not" operator to switch 1s into 0s and 0s into 1s.

% First, let's make some random data of ones and zeros:

N = 10; % The number of columns == 10

M = rand(N) > .5

% Now, Get a vector of values that you want where the 1s are:

vals1 = rand(1,N)

% Let's make it the same shape as 'x':

vals1 = repmat(vals1,N,1)

% And get a vector of values for the columns where the 0s are:

vals0 = -rand(1,N)

% Replicate them into the shape of 'x', also:

vals0 = repmat(vals0,N,1)

% Now, let's do the replacements:

res = zeros(size(M));

% For the ones spots:

res(logical(M)) = vals1(logical(M));

% And now for the zeros:

res(~logical(M)) = vals0(~logical(M));

The calls to 'logical()' just makes sure that the 'M' matrix is logical, even if it wasn't to begin with. I think that this would be much more flexible than going column by column. The downside is the allocation of the extra (possibly big) matrices 'vals1' and 'vals0'.

Sign in to comment.

Sign in to answer this question.

Opportunities for recent engineering grads.

Apply Today
## 2 Comments

## Direct link to this comment

https://au.mathworks.com/matlabcentral/answers/420571-searching-and-replacing-values-in-a-matrix#comment_613919

⋮## Direct link to this comment

https://au.mathworks.com/matlabcentral/answers/420571-searching-and-replacing-values-in-a-matrix#comment_613919

## Direct link to this comment

https://au.mathworks.com/matlabcentral/answers/420571-searching-and-replacing-values-in-a-matrix#comment_613922

⋮## Direct link to this comment

https://au.mathworks.com/matlabcentral/answers/420571-searching-and-replacing-values-in-a-matrix#comment_613922

Sign in to comment.