normalize all but the zeros in a vector?

I have a vector that contains 0s, something like this [44 0 23 19 0 0 30]
and I want to normalize the non-0 elements to 1-10, for instance, but the 0s keep messing it up.
Is there a way (hopefully without using loops) to normalize while not affecting the 0s? In other words, take the values from 19-44 and convert them to stretch over 1-10.

 Risposta accettata

Dyuman Joshi
Dyuman Joshi il 24 Dic 2023
Modificato: Dyuman Joshi il 24 Dic 2023
%Input
in = [44 0 23 19 0 0 30];
%Lazy preallocation, assuming all values are finite and not NaNs
out = 0*in;
%Indexing for non-zeros values
idx = in~=0;
%Output
out(idx) = rescale(in(idx), 1, 10)
out = 1×7
10.0000 0 2.4400 1.0000 0 0 4.9600

6 Commenti

Works like a charm, thank you so much!!!
Not complaining, but the "lazy preallocation" can potentially, rarely, produce artifacts that might lead to some debugging time. Suppose the vector contains some inf elements? Then a multiplication by zero will produce NaNs.
x = [1 2 3 4 inf 5 6];
y = 0*x
y = 1×7
0 0 0 0 NaN 0 0
So if you were expecting all zero elements in there, because you multiplied by zero, then you would be surprised. A minor point, really.
You are right, @John D'Errico, and the reason you have mentioned is why I use the phrase "lazy preallocation".
Since I have worked mostly with finite and non-NaN (that felt weird to write) values, it has became kind of ingrained in me to use that method.
I have edited my comment to incorporate assumptions made to use it accordingly.
Honestly, will the problem I mentioned ever come up? Probably not often. But as soon as I say that, it will happen. Anyway, my ingrained habit is to use
y = zeros(size(x));
which is not much harder to write than 0*x. It is surely faster to execute, but the difference will be literally immeasurable unless the array is pretty large.
x = rand(10000);
timeit(@() 0*x)
ans = 0.1748
timeit(@() zeros(size(x)))
ans = 7.4274e-06
"But as soon as I say that, it will happen."
Haha, yes.
Mine used to be that too, but I am not sure how it changed into multiplying with 0. I think I'll go back to using zeros() soon, specially noting the difference in speed.
However, keeping performance in mind, maybe I should revisit this thread - https://in.mathworks.com/matlabcentral/answers/51411-initialize-a-mxn-matrix-with-the-same-number#answer_453549
y = zeros(size(x), 'like', x);
for extra robustness.

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Mathematics in Centro assistenza e File Exchange

Prodotti

Release

R2022a

Tag

Community Treasure Hunt

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

Start Hunting!

Translated by