How to standardize an array so that the maximum value is 1 and minimum is -1 keeping the zero value as zero?

13 ビュー (過去 30 日間)
Abhishek Chakraborty 2022 年 12 月 8 日

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 件のコメント-1 件の古いコメントを表示-1 件の古いコメントを非表示
Bora Eryilmaz 2022 年 12 月 8 日

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.

サインインしてコメントする。

採用された回答

Mathieu NOE 2022 年 12 月 8 日
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 件のコメントなしを表示なしを非表示
Abhishek Chakraborty 2022 年 12 月 9 日
Wow. This is such an interesting way to handle this problem. I also checked it for the 2-D case and it works perfectly:
A = [1.37 -3.299 0.1;5.33 0 7.1;-8.222 -0.09 -22];
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,'--');
A1 =
1.3700
5.3300
0
0.1000
7.1000
A2 =
-8.2220
-3.2990
-0.0900
-22.0000
>> B
B =
0.1930 -0.1500 0.0141
0.7507 0 1.0000
-0.3737 -0.0041 -1.0000
Thanks a lot.
Mathieu NOE 2022 年 12 月 9 日
My pleasure !

サインインしてコメントする。

その他の回答 (5 件)

Image Analyst 2022 年 12 月 9 日
Try this:
A = randi(10, 1, 18) - 5
A = 1×18
-2 3 2 5 -4 -1 0 0 -3 -2 5 3 2 -1 3 -3 -4 -4
A(A<0) = -A(A<0) / min(A(A<0)) % FIrst rescale negative numbers to -1 to 0
A = 1×18
-0.5000 3.0000 2.0000 5.0000 -1.0000 -0.2500 0 0 -0.7500 -0.5000 5.0000 3.0000 2.0000 -0.2500 3.0000 -0.7500 -1.0000 -1.0000
A(A>0) = A(A>0) / max(A(A>0)) % Next rescale positive numbers to 0 to 1
A = 1×18
-0.5000 0.6000 0.4000 1.0000 -1.0000 -0.2500 0 0 -0.7500 -0.5000 1.0000 0.6000 0.4000 -0.2500 0.6000 -0.7500 -1.0000 -1.0000
1 件のコメント-1 件の古いコメントを表示-1 件の古いコメントを非表示
Abhishek Chakraborty 2022 年 12 月 9 日
Thanks a lot.

サインインしてコメントする。

Stephen23 2022 年 12 月 9 日

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)
B = 1×7
-0.2500 -0.5000 -0.7500 -1.0000 0 0.5000 1.0000
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)
B = 1×4
-0.2500 -0.5000 -0.7500 -1.0000
The cases min==0 or max==0 must be handled separately. Note that all of the alorithms have similar limitations.
1 件のコメント-1 件の古いコメントを表示-1 件の古いコメントを非表示
Stephen23 2022 年 12 月 9 日

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)
B = 1×7
0.5000 0.3333 0.1667 0 0.6667 0.8333 1.0000
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)
B = 1×7
2.9299 2.8594 2.7888 2.7183 3.0005 3.0710 3.1416
etc. etc.

サインインしてコメントする。

DGM 2022 年 12 月 9 日

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
A = 1×16
-10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 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 件のコメントなしを表示なしを非表示
Stephen23 2022 年 12 月 9 日

A = [-1,-2,-3,-4,0,1];
B = A/max(abs([min(A(:)),max(A(:))]))
B = 1×6
-0.2500 -0.5000 -0.7500 -1.0000 0 0.2500
DGM 2022 年 12 月 9 日

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 2022 年 12 月 9 日
A "smooth" mapping
% Data
a=randi([-10,10],1,5)
a = 1×5
2 -4 -5 2 -4
pp=pchip([min(a) 0 max(a)], -1:1);
normfun=@(a) ppval(pp,a)
normfun = function_handle with value:
@(a)ppval(pp,a)
an=normfun(a)
an = 1×5
1.0000 -0.9447 -1.0000 1.0000 -0.9447
% Check the mapping curve
densesample = linspace(min(a),max(a));
plot(densesample,normfun(densesample))
0 件のコメント-2 件の古いコメントを表示-2 件の古いコメントを非表示

サインインしてコメントする。

Matt J 2022 年 12 月 8 日

A=[-1 -2 -3 -4 0 1]
A = 1×6
-1 -2 -3 -4 0 1
I=logical(A);
StdA=A;
StdA(I) = rescale(A(I),-1,1)
StdA = 1×6
0.2000 -0.2000 -0.6000 -1.0000 0 1.0000
8 件のコメント6 件の古いコメントを表示6 件の古いコメントを非表示
DGM 2022 年 12 月 9 日
You're right. There isn't any "making 1/0 work", but those cases can be conditionally handled. Since normalize() and similar tools handle those cases by returning zeros, that would suffice for the edit that I made.
I don't know what's appropriate either. I'm here surrounded by a lot of people who know more than I do about what's meaningful in terms of statistics or signal processing. I just want to know if the answer that's needed isn't an answer to the original question (an XY problem). I suppose I'm also kind of throwing out an idea for future readers, regardless of OP's decision.
FWIW, I removed my original comment, since you've updated your answer and I guess Bruno deleted his some time before I even posted the comment.
Bruno Luong 2022 年 12 月 9 日

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.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeGet Started with MATLAB についてさらに検索

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by