How do I replace the elements of a matrix (x) that are more than one standard deviation (s) away from the mean (m) with the nearest of m ± s

4 次查看(过去 30 天)
The catch is i need to do this as a one line command assuming i already have x
so far i can do it for replacing elements greater than m+s with m+s and for replacing elements lower than m-s with m-s with the two commands shown below but cant think of a way to put them into a one line command.
x(x>(mean2(x)+std2(x)))=(mean2(x)+std2(x))
x(x<(mean2(x)-std2(x)))=(mean2(x)-std2(x))
Appologies for my lack of knowledge - i'm quite new to matlab
  3 个评论
Guiche
Guiche 2013-12-12
It is in a way I'm trying to expand my MATLAB knowledge with some mini challenges from a text book I hope that's not a problem

请先登录,再进行评论。

回答(3 个)

Azzi Abdelmalek
Azzi Abdelmalek 2013-12-12
x=rand(10)
m2=mean2(x);
s2=std2(x);
idx1=x>m2+s2;
idx2=x<m2-s2;
x(idx1)=m2+s2;
x(idx2)=m2-s2;
x
  6 个评论
Guiche
Guiche 2013-12-12
编辑:Guiche 2013-12-12
ok i see - so its purely inefficient. This makes sense but for this specific thing i wanted to do i was trying to be efficient in number of commands not number of calculations. i understand that this is not very conventional and potentially bad practice but i am attempting these tasks to help teach myself ways of thinking outside the box and learning other options with this language. - i don't think conversations like this are appreciated on this site as it deters from the "answers" part. but if you would like to continue the conversation you are welcome to pm me.
Azzi Abdelmalek
Azzi Abdelmalek 2013-12-12
If I have to choose between elegant way or efficient way, I will say efficient. It's good to look for elegant way, but without affecting the efficiency. Also one line does not mean one command.

请先登录,再进行评论。


Guiche
Guiche 2013-12-12
Somebody commented earlier with a very close answer but forgot to add the mean they seem to have since deleted their comment but it helped immensely. This was the command that i got to work by editing theirs:
x(abs(x)>std2(x)+mean2(x)) = mean2(x)+(sign(x(abs(x)>std2(x)))*std2(x))
Cheers my friend whomever you were

John D'Errico
John D'Errico 2013-12-12
编辑:John D'Errico 2013-12-12
It seems like nobody knows how to use min and max, instead they use indexing. Silly idea that, especially when the answer is trivial with min and max. The point is to learn to use these built-in functions in fully vectorized form.
I'll write it in 3 lines to avoid computing the mean and std twice. It also makes it easier to read so you can follow what I did.
s = std(x);
mu = mean (x);
x = max(min(x,mu + s),mu - s);
Of course, it is trivial to write in one line if you wish, but I prefer maximally readable and maximally efficient code where those goals are reasonable.
x = max(min(x,mean(x) + std(x)),mean(x) - std(x));
See that the one-liner computes the mean and std TWICE, not FOUR times as others would think you need. Even so, an extra line or so of code is not a bad thing.
By the way, I did see that you wonder what is wrong with calling mean and std multiple times. The fact is, it is not an obscene thing to call mean(x) twice, when calling it once was simple. However, imagine that x is a vector with length in the millions, and you need to do that same computation often. Calling a function twice costs twice as much time as calling it once.
Good programming practice suggests that you get used to doing things efficiently. Why waste CPU cycles that need not be wasted? One day good programming practices will save you some serious time. Of course, if you never learn those good practices, then you are out of luck.

类别

Help CenterFile Exchange 中查找有关 Characters and Strings 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by