Searching and replacing values in a matrix
77 次查看(过去 30 天)
显示 更早的评论
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?
2 个评论
aepound
2018-9-24
You still need to include the particular column in the outer x index:
x(x(:,1) == 0,1) = 0.75;
采纳的回答
James Tursa
2018-9-24
编辑:James Tursa
2018-9-24
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);
4 个评论
Nicole Peltier
2018-9-24
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
2018-9-24
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.
更多回答(2 个)
Angie Ojeda
2021-4-19
Hi, for replace a value you can try this
a = magic(3)
a =
8 1 6
3 5 7
4 9 2
a(a==8)=5
a =
5 1 6
3 5 7
4 9 2
a(a==5)=0
a =
0 1 6
3 0 7
4 9 2
0 个评论
aepound
2018-9-24
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'.
0 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Matrix Indexing 的更多信息
产品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!