【问题标题】:How to Normalize data with NaN values in python如何在 python 中使用 NaN 值规范化数据
【发布时间】:2018-06-24 20:04:06
【问题描述】:

我使用的数据有一些空值,我想使用 knn 插补来插补空值。为了有效地估算我想规范化数据。

normalizer = Normalizer() #from sklearn.preprocessing
normalizer.fit_transform(data[num_cols]) #columns with numeric value

错误:输入包含 NaN、无穷大或对于 dtype('float64') 来说太大的值。

那么我如何规范化具有 NaN 的数据

【问题讨论】:

  • 您可以编写自己的函数来规范化数据

标签: python dataframe normalize


【解决方案1】:

sklearn.preprocessing.Normalizer 不像迄今为止的其他答案那样大约为 0 均值、1 标准差归一化。 Normalizer() 是关于将行缩放到单位范数,例如到improve clustering 或原始问题归集。您可以阅读herehere 的区别。对于缩放行,您可以尝试以下操作:

import numpy as np

A = np.array([[  7,     4,   5,  7000],
              [  1,   900,   9,   nan],
              [  5, -1000, nan,   100],
              [nan,   nan,   3,  1000]])

#Compute NaN-norms
L1_norm = np.nansum(np.abs(A), axis=1)
L2_norm = np.sqrt(np.nansum(A**2, axis=1))
max_norm = np.nanmax(np.abs(A), axis=1)

#Normalize rows
A_L1 =  A / L1_norm[:,np.newaxis] # A.values if Dataframe
A_L2 =  A / L2_norm[:,np.newaxis]
A_max = A / max_norm[:,np.newaxis]

#Check that it worked
L1_norm_after = np.nansum(np.abs(A_L1), axis=1)
L2_norm_after = np.sqrt(np.nansum(A_L2**2, axis=1))
max_norm_after = np.nanmax(np.abs(A_max), axis=1)

 In[182]: L1_norm_after
Out[182]: array([1., 1., 1., 1.])

 In[183]: L2_norm_after
Out[183]: array([1., 1., 1., 1.])

 In[184]: max_norm_after
Out[184]: array([1., 1., 1., 1.])

如果 Google 将您带到这里(像我一样)并且您想使用估算器 API 将列标准化为 0 均值、1 标准差,您可以使用 sklearn.preprocessing.StandardScaler。它可以处理 NaN(在 sklearn 0.20.2 上测试过,我记得它不适用于某些旧版本)。

from numpy import nan, nanmean
from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()

A = [[  7,     4,   5,  7000],
     [  1,   900,   9,   nan],
     [  5, -1000, nan,   100],
     [nan,   nan,   3,  1000]]

scaler.fit(A)

In [45]: scaler.mean_
Out[45]: array([4.33333333,  -32.,    5.66666667, 2700.])

In [46]: scaler.transform(A)
Out[46]: array([[ 1.06904497,  0.04638641, -0.26726124,  1.40399977],
                [-1.33630621,  1.20089267,  1.33630621,         nan],
                [ 0.26726124, -1.24727908,         nan, -0.84893009],
                [        nan,         nan, -1.06904497, -0.55506968]])

In [54]: nanmean(scaler.transform(A), axis=0)
Out[54]: array([ 1.48029737e-16,  0.00000000e+00, -1.48029737e-16,0.00000000e+00])

【讨论】:

    【解决方案2】:

    此方法将所有列归一化为 [0,1],NaN 仍然是 NaN

    def norm_to_zero_one(df):
        return (df - df.min()) * 1.0 / (df.max() - df.min())
    

    例如:

    [In]
    df = pd.DataFrame({'A': [10, 20, np.nan, 30],
                       'B': [1, np.nan, 10, 5]})
    df = df.apply(norm_to_zero_one)
    [Out]
         A         B
    0  0.0  0.000000
    1  0.5       NaN
    2  NaN  1.000000
    3  1.0  0.444444
    

    df.max()df.min() 返回每​​列的最大值和最小值。

    【讨论】:

      【解决方案3】:

      我建议不要在 sklearn 中使用 normalize,因为它不处理 NaN。您可以简单地使用下面的代码来规范化您的数据。

      df['col']=(df['col']-df['col'].min())/(df['col'].max()-df['col'].min())
      

      上述方法在规范化数据时忽略 NaN

      【讨论】:

      • 使用这个公式后如何反规范化?
      • 您到底想做什么?如果您想取回原始值,请将其保存在变量中。我建议你应该问一些新的问题。
      • 哦,抱歉,我的意思是……想象一下您将“y”值标准化。因此,在预测之后,“yhat”也将被归一化。不使用 MinMaxScaler,但使用您的公式,我如何对 'yhat' 值进行反规范化?
      猜你喜欢
      • 2016-10-11
      • 2021-03-09
      • 1970-01-01
      • 1970-01-01
      • 2016-07-23
      • 2020-07-31
      • 2010-11-20
      • 2020-05-29
      • 2010-09-12
      相关资源
      最近更新 更多