python 归一化以使范围为[0,1]

snz8szmq  于 2023-01-19  发布在  Python
关注(0)|答案(9)|浏览(228)

我有一个巨大的数据集,从中我得到了两组数据点,然后我必须对它们进行绘图和比较。这两个绘图的范围不同,所以我希望它们在[0,1]的范围内。对于下面的代码和一个特定的数据集,我得到了一条常数为1的线作为数据集绘图,但这种归一化对其他数据集也很有效:

plt.plot(range(len(rvalue)),np.array(rvalue)/(max(rvalue)))

对于此代码:

oldrange = max(rvalue) - min(rvalue)  # NORMALIZING
newmin = 0
newrange = 1 + 0.9999999999 - newmin
normal = map(
    lambda x, r=float(rvalue[-1] - rvalue[0]): ((x - rvalue[0]) / r)*1 - 0, 
    rvalue)
plt.plot(range(len(rvalue)), normal)

我得到错误:

ZeroDivisionError: float division by zero

对于所有的数据集。我不能想出如何让两个图在一个范围内进行比较。

0ejtzxu1

0ejtzxu11#

使用以下方法,使用数据序列中的最小值和最大值在0到1范围内归一化数据:

import numpy as np

def NormalizeData(data):
    return (data - np.min(data)) / (np.max(data) - np.min(data))
drkbr07n

drkbr07n2#

使用scikit:www.example.comhttp://scikit-learn.org/stable/modules/preprocessing.html#scaling-features-to-a-range
它有内置的功能来将特征缩放到指定的范围。你会在这里找到其他的功能来规范化和标准化。
请看这个例子:

>>> import numpy as np
>>> from sklearn import preprocessing
>>> X_train = np.array([[ 1., -1.,  2.],
...                     [ 2.,  0.,  0.],
...                     [ 0.,  1., -1.]])
...
>>> min_max_scaler = preprocessing.MinMaxScaler()
>>> X_train_minmax = min_max_scaler.fit_transform(X_train)
>>> X_train_minmax
array([[ 0.5       ,  0.        ,  1.        ],
       [ 1.        ,  0.5       ,  0.33333333],
       [ 0.        ,  1.        ,  0.        ]])
wmtdaxz3

wmtdaxz33#

scikit_learn有一个用于此的函数
sklearn.preprocessing.minmax_scale(X, feature_range=(0, 1), axis=0, copy=True)
比使用MinMaxScale类更方便。
https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.minmax_scale.html#sklearn.preprocessing.minmax_scale

jchrr9hc

jchrr9hc4#

查找数组的范围是由numpy内置函数numpy.ptp()提供的,您的问题可以通过以下方式解决:

#First we should filter input_array so that it does not contain NaN or Inf.
input_array=np.array(some_data)
if np.unique(input_array).shape[0]==1:
    pass #do thing if the input_array is constant
else:
    result_array=(input_array-np.min(input_array))/np.ptp(input_array)
#To extend it to higher dimension, add axis= kwarvg to np.min and np.ptp
xxslljrj

xxslljrj5#

我试着把事情简单化。试试这个:

oldmin = min(rvalue)
oldmax = max(rvalue)
oldrange = oldmax - oldmin
newmin = 0.
newmax = 1.
newrange = newmax - newmin
if oldrange == 0:            # Deal with the case where rvalue is constant:
    if oldmin < newmin:      # If rvalue < newmin, set all rvalue values to newmin
        newval = newmin
    elif oldmin > newmax:    # If rvalue > newmax, set all rvalue values to newmax
        newval = newmax
    else:                    # If newmin <= rvalue <= newmax, keep rvalue the same
        newval = oldmin
    normal = [newval for v in rvalue]
else:
    scale = newrange / oldrange
    normal = [(v - oldmin) * scale + newmin for v in rvalue]

plt.plot(range(len(rvalue)),normal)

我能看到ZeroDivisionError的唯一原因是右值中的数据是常数(所有值都相同),是这样吗?

92vpleto

92vpleto6#

为了给其他答案提供一些背景知识,下面是一个推导:
通过点(x1, y1)(x2, y2)的直线可表示为:

y = y1 + slope * (x - x1)

其中

slope = (y2 - y1) / (x2 - x1)

现在从01的归一化意味着

y1 = 0, y2 = 1

以及

x1 = x_min, x2 = x_max

(or反之亦然,具体取决于您的需要)
然后该等式简化为

y = (x - x_min) / (x_max - x_min)
njthzxwz

njthzxwz7#

你可以将样本中的每个数字除以样本中所有数字的总和。

tct7dpnv

tct7dpnv8#

我更喜欢类似于Marissa Novak'sRZhang's答案的sci-kit学习预处理工具,尽管我喜欢不同的结构:

import numpy as np
from sklearn import preprocessing

# data
years = [1972 1973 1974 1975 1976 1977 1978 1979 1984 1986 1989 1993 1994 1997
 1998 1999 2002 2004 2010 2017 2018 2021 2022]

# specify the range to which you want to scale
rng = (0, 1) 

# initiate the scaler
# 0,1 is the default feature_range and doesn't have to be specified
scaler = preprocessing.MinMaxScaler(feature_range=(rng[0], rng[1]))

# apply the scaler
normed = scaler.fit_transform(np.array(years).reshape(-1, 1))

# the output is an array of arrays, so tidy the dimensions
norm_lst = [round(i[0],2) for i in normed]

虽然这比RZhang's answer更冗长,而且不太适合原始的“巨大”数据集用例,但我更喜欢它,因为它对我的大多数应用程序(〈10^3个值)都具有可读性。
rng =(0,1)得出:

[0.0, 0.02, 0.04, 0.06, 0.08, 0.1, 0.12, 0.14, 0.24, 0.28, 0.34, 0.42, 0.44, 0.5, 0.52, 0.54, 0.6, 0.64, 0.76, 0.9, 0.92, 0.98, 1.0]

例如,rng =(0.3,0.8),得到:

[0.3, 0.31, 0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.42, 0.44, 0.47, 0.51, 0.52, 0.55, 0.56, 0.57, 0.6, 0.62, 0.68, 0.75, 0.76, 0.79, 0.8]
ef1yzkbh

ef1yzkbh9#

一个简单的方法来规范化0和1之间的任何值,只是除以最大值的所有值,从所有的值。将得到的值在0到1的范围。

相关问题