14

我有一个庞大的数据集,从中我得出两组数据点,然后我必须对其进行绘图和比较。这两个图的范围不同,所以我希望它们在[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

对于所有数据集。我无法弄清楚如何将两个图都放在一个范围内进行比较。

4

8 回答 8

29

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

import numpy as np

def NormalizeData(data):
    return (data - np.min(data)) / (np.max(data) - np.min(data))
于 2019-03-13T11:59:14.667 回答
15

使用 scikit: http ://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.        ]])
于 2016-09-13T23:18:02.773 回答
7

查找数组的范围由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
于 2013-08-22T14:42:23.680 回答
6

scikit_learn 有一个功能
sklearn.preprocessing.minmax_scale(X, feature_range=(0, 1), axis=0, copy=True)

比使用 Class MinMaxScale 更方便。

https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.minmax_scale.html#sklearn.preprocessing.minmax_scale

于 2019-10-10T22:23:13.800 回答
2

我试图简化一些事情。尝试这个:

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是右值中的数据是否恒定(所有值都相同)。是这样吗?

于 2013-08-22T12:35:13.793 回答
1

只是为了为其他答案提供一些背景,这里是一个推导:

一条通过点的直线(x1, y1)(x2, y2)可以表示为:

y = y1 + slope * (x - x1)

在哪里

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

0现在,从to标准化1意味着

y1 = 0, y2 = 1

x1 = x_min, x2 = x_max

(反之亦然,取决于您的需要)

然后等式简化为

y = (x - x_min) / (x_max - x_min)
于 2021-07-09T07:43:22.453 回答
0

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

于 2021-08-26T11:11:56.160 回答
-1

将 0 和 1 之间的任何值标准化的一种简单方法是将所有值除以所有值的最大值。将带来介于 0 到 1 之间的值。

于 2019-03-14T09:24:35.343 回答