How to standardize an array so that the maximum value is 1 and minimum is -1 keeping the zero value as zero?
11 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Abhishek Chakraborty
am 8 Dez. 2022
Bearbeitet: Bruno Luong
am 9 Dez. 2022
I wanted to standardize an array so that the maximum value of the array takes the value "1" and the minimum value takes the value "-1" keeping the original value "0" in the array as "0" in the standardized array?
For example,
A=[-1 -2 -3 -4 0 1];
StdA=(A-min(A(:)))/(max(A(:))-min(A(:)))
StdA=2*StdA-1
But by doing this sort of standardization, I get:
StdA =
0.2000 -0.2000 -0.6000 -1.0000 0.6000 1.0000
However, I would want to keep 0 as 0 i.e., StdA(:,5)=0 with the maximum and minimum values of the array taking +1 and -1 values.
How to do it? Kindly help me with the same.
1 Kommentar
Bora Eryilmaz
am 8 Dez. 2022
Bearbeitet: Bora Eryilmaz
am 8 Dez. 2022
This cannot be done using a linear standardization function of the form y = a*x + b since you are trying to enforce 3 constraints, whereas a linear equation can only accommodate 2.
Akzeptierte Antwort
Mathieu NOE
am 8 Dez. 2022
hello
this can only be accomplished if you accept that the positive and negative parts of your signal are normalized by a different scale factor

A=[-1 -2 -3 -4 0 1];
B = A;
% normalisation of the positive values
id1 = A>=0;
A1 = A(id1)
A1 = A1./max(A1);
B(id1) = A1;
% normalisation of the negative values
id2 = A<0;
A2 = A(id2)
A2 = A2./max(-A2);
B(id2) = A2;
plot(A,'-d'); hold on
plot(B,'--');
2 Kommentare
Weitere Antworten (5)
Image Analyst
am 9 Dez. 2022
Try this:
A = randi(10, 1, 18) - 5
A(A<0) = -A(A<0) / min(A(A<0)) % FIrst rescale negative numbers to -1 to 0
A(A>0) = A(A>0) / max(A(A>0)) % Next rescale positive numbers to 0 to 1
Stephen23
am 9 Dez. 2022
Bearbeitet: Stephen23
am 9 Dez. 2022
In just one simple step, assuming that the min<0 and max>0:
A = [-1,-2,-3,-4,0,1,2];
B = interp1([min(A),0,max(A)],[-1,0,1],A)
Or in case the values do not cross zero, the addition of ABS():
A = [-1,-2,-3,-4];
B = interp1([-abs(min(A)),0,abs(max(A))],[-1,0,1],A)
The cases min==0 or max==0 must be handled separately. Note that all of the alorithms have similar limitations.
1 Kommentar
Stephen23
am 9 Dez. 2022
Bearbeitet: Stephen23
am 9 Dez. 2022
Note how this method can be easily modified to efficiently scale any number of ranges to any continuous scales.
For example, the classic "0 to 1":
A = [-1,-2,-3,-4,0,1,2];
B = interp1([min(A),max(A)],[0,1],A)
or slightly more esoteric "e to pi":
A = [-1,-2,-3,-4,0,1,2];
B = interp1([min(A),max(A)],[exp(1),pi],A)
etc. etc.
DGM
am 9 Dez. 2022
Bearbeitet: DGM
am 9 Dez. 2022
I'm not into statistics, so I have no idea if this has merit. I'm occasionally after preserving linearity and the center (zero) moreso than constraining zero and both extrema. If so,
% input vector
A = -10:5
% normalize with respect to zero and furthest extrema
B = A/max(abs([min(A(:)) max(A(:))]));
plot(A,B);
This is a way to normalize a nominally zero-centered signal (e.g. audio) without distorting it or adding DC bias.
Note that this still works if the data does not cross zero.
2 Kommentare
DGM
am 9 Dez. 2022
Bearbeitet: DGM
am 9 Dez. 2022
Correct. As I mentioned, I am questioning whether the requested constraints are appropriate. Instead of constraining zero and both extrema, I'm constraining zero and one extrema so as to maintain linearity.
As for my oversight, depending on the expected behavior, the all-zero case can be handled easily enough. I'm sure there are other potential problems; I wasn't out to write something robust so much as to suggest an idea.
% normalize with respect to zero and furthest extrema
nf = max(abs([min(A(:)) max(A(:))]));
if nf == 0 % input is all zeros
B = A;
else
B = A/nf;
end
Bruno Luong
am 9 Dez. 2022
A "smooth" mapping
% Data
a=randi([-10,10],1,5)
pp=pchip([min(a) 0 max(a)], -1:1);
normfun=@(a) ppval(pp,a)
an=normfun(a)
% Check the mapping curve
densesample = linspace(min(a),max(a));
plot(densesample,normfun(densesample))
0 Kommentare
Matt J
am 8 Dez. 2022
Bearbeitet: Matt J
am 8 Dez. 2022
A=[-1 -2 -3 -4 0 1]
I=logical(A);
StdA=A;
StdA(I) = rescale(A(I),-1,1)
8 Kommentare
Bruno Luong
am 9 Dez. 2022
Bearbeitet: Bruno Luong
am 9 Dez. 2022
I remove my first code with polyfit since I think it sometime give non-monotonic map, which to my mind is not "standardize" whatever that means. It but "works" if 0 falls outside the data.
I'll give IMO opinion better solution since it is unlikely to give a non-monotonic mapping.
Siehe auch
Kategorien
Find more on Numeric Types in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!