代码之家  ›  专栏  ›  技术社区  ›  user7852656

按多个列的dataframe规范化每一列[duplicate]

  •  0
  • user7852656  · 技术社区  · 6 年前

    测向:

    A     B   C
    1000  10  0.5
    765   5   0.35
    800   7   0.09
    

    知道如何规范化这个数据帧中每个值都在0和1之间的列吗?

    我想要的输出是:

    A     B    C
    1     1    1
    0.765 0.5  0.7
    0.8   0.7  0.18(which is 0.09/0.5)
    
    0 回复  |  直到 4 年前
        1
  •  288
  •   Amir Imani    5 年前

    您可以使用sklearn包及其相关的预处理实用程序来规范化数据。

    import pandas as pd
    from sklearn import preprocessing
    
    x = df.values #returns a numpy array
    min_max_scaler = preprocessing.MinMaxScaler()
    x_scaled = min_max_scaler.fit_transform(x)
    df = pd.DataFrame(x_scaled)
    

    documentation

        2
  •  515
  •   Cina    4 年前

    一个简单的方法就是 :(这里我想使用均值归一化)

    normalized_df=(df-df.mean())/df.std()
    

    要使用最小最大规格化:

    normalized_df=(df-df.min())/(df.max()-df.min())
    

    Edit:为了解决一些问题,需要说明Pandas在上面的代码中自动应用了按列的函数。

        3
  •  60
  •   Community Jaime Torres    7 年前

    根据这篇文章: https://stats.stackexchange.com/questions/70801/how-to-normalize-data-to-0-1-range

    您可以执行以下操作:

    def normalize(df):
        result = df.copy()
        for feature_name in df.columns:
            max_value = df[feature_name].max()
            min_value = df[feature_name].min()
            result[feature_name] = (df[feature_name] - min_value) / (max_value - min_value)
        return result
    

    你不必一直担心你的价值观是消极的还是积极的。值应该很好地分布在0和1之间。

        4
  •  45
  •   tschm    7 年前

    def f(s):
        return s/s.max()
    
    frame.apply(f, axis=0)
    

    或者更简洁:

       frame.apply(lambda x: x/x.max(), axis=0)
    
        5
  •  35
  •   j sad    7 年前

    如果您喜欢使用sklearn包,可以使用pandas保留列和索引名 loc

    from sklearn.preprocessing import MinMaxScaler
    
    scaler = MinMaxScaler() 
    scaled_values = scaler.fit_transform(df) 
    df.loc[:,:] = scaled_values
    
        6
  •  30
  •   raullalves    6 年前

    可以创建要规范化的列列表

    column_names_to_normalize = ['A', 'E', 'G', 'sadasdsd', 'lol']
    x = df[column_names_to_normalize].values
    x_scaled = min_max_scaler.fit_transform(x)
    df_temp = pd.DataFrame(x_scaled, columns=column_names_to_normalize, index = df.index)
    df[column_names_to_normalize] = df_temp
    


    然而 相反的 ,选择一个列列表 不要

    column_names_to_not_normalize = ['B', 'J', 'K']
    column_names_to_normalize = [x for x in list(df) if x not in column_names_to_not_normalize ]
    
        7
  •  29
  •   Basil Musa    6 年前

    简单就是美丽:

    df["A"] = df["A"] / df["A"].max()
    df["B"] = df["B"] / df["B"].max()
    df["C"] = df["C"] / df["C"].max()
    
        8
  •  26
  •   BhishanPoudel    4 年前

    规范化方法的详细示例

    • 熊猫标准化(无偏)
    • 有偏与无偏影响机器学习吗?

    参考文献: Wikipedia: Unbiased Estimation of Standard Deviation

    示例数据

    import pandas as pd
    df = pd.DataFrame({
                   'A':[1,2,3],
                   'B':[100,300,500],
                   'C':list('abc')
                 })
    print(df)
       A    B  C
    0  1  100  a
    1  2  300  b
    2  3  500  c
    

    使用熊猫进行归一化(给出无偏估计)

    标准化时,我们只需减去平均值,然后除以标准差。

    df.iloc[:,0:-1] = df.iloc[:,0:-1].apply(lambda x: (x-x.mean())/ x.std(), axis=0)
    print(df)
         A    B  C
    0 -1.0 -1.0  a
    1  0.0  0.0  b
    2  1.0  1.0  c
    

    sklearn 你会得到不同的输出!

    import pandas as pd
    
    from sklearn.preprocessing import StandardScaler
    scaler = StandardScaler()
    
    
    df = pd.DataFrame({
                   'A':[1,2,3],
                   'B':[100,300,500],
                   'C':list('abc')
                 })
    df.iloc[:,0:-1] = scaler.fit_transform(df.iloc[:,0:-1].to_numpy())
    print(df)
              A         B  C
    0 -1.224745 -1.224745  a
    1  0.000000  0.000000  b
    2  1.224745  1.224745  c
    

    对sklearn有偏见的估计是否会降低机器学习的能力?

    sklearn.preprocessing.scale 说明使用有偏估计不太可能影响机器学习算法的性能,我们可以安全地使用它们。

    根据官方文件:

    我们对标准差使用有偏估计,相当于 numpy.std(x, ddof=0) ddof 不太可能影响模型性能。

    最小-最大标度中没有标准差计算。所以大熊猫和大熊猫的结果是一样的。

    import pandas as pd
    df = pd.DataFrame({
                   'A':[1,2,3],
                   'B':[100,300,500],
                 })
    (df - df.min()) / (df.max() - df.min())
         A    B
    0  0.0  0.0
    1  0.5  0.5
    2  1.0  1.0
    
    
    # Using sklearn
    from sklearn.preprocessing import MinMaxScaler
    
    scaler = MinMaxScaler() 
    arr_scaled = scaler.fit_transform(df) 
    
    print(arr_scaled)
    [[0.  0. ]
     [0.5 0.5]
     [1.  1. ]]
    
    df_scaled = pd.DataFrame(arr_scaled, columns=df.columns,index=df.index)
    print(df_scaled)
         A    B
    0  0.0  0.0
    1  0.5  0.5
    2  1.0  1.0
    
        9
  •  13
  •   Daniele    10 年前

    我认为在熊猫身上更好的方法就是

    df = df/df.max().astype(np.float64)
    

    编辑 如果数据框中出现负数,则应改用负数

    df = df/df.loc[df.abs().idxmax()].astype(np.float64)
    
        10
  •  11
  •   Ozkan Serttas    7 年前

    桑德曼和普拉文给出的解决方案非常好。唯一的问题是,如果在数据框的其他列中有分类变量,则此方法需要进行一些调整。

    我对这类问题的解决方案如下:

     from sklearn import preprocesing
     x = pd.concat([df.Numerical1, df.Numerical2,df.Numerical3])
     min_max_scaler = preprocessing.MinMaxScaler()
     x_scaled = min_max_scaler.fit_transform(x)
     x_new = pd.DataFrame(x_scaled)
     df = pd.concat([df.Categoricals,x_new])
    
        11
  •  8
  •   masouduut94    5 年前

    您可能希望一些列被规范化,而其他列保持不变,就像一些数据标签或分类列保持不变的回归任务一样,因此我建议您使用这种pythonic方式(它是@shg和@Cina answers的组合):

    features_to_normalize = ['A', 'B', 'C']
    # could be ['A','B'] 
    
    df[features_to_normalize] = df[features_to_normalize].apply(lambda x:(x-x.min()) / (x.max()-x.min()))
    
        12
  •  6
  •   Yuan    5 年前

    这只是简单的数学。答案应该如下所示。

    normed_df = (df - df.min()) / (df.max() - df.min())
    
        13
  •  4
  •   Davoud Taghawi-Nejad    4 年前
    df_normalized = df / df.max(axis=0)
    
        14
  •  3
  •   Chad    5 年前

    这是如何使用列表理解按列执行的:

    [df[col].update((df[col] - df[col].min()) / (df[col].max() - df[col].min())) for col in df.columns]
    
        15
  •  2
  •   shg    6 年前
    def normalize(x):
        try:
            x = x/np.linalg.norm(x,ord=1)
            return x
        except :
            raise
    data = pd.DataFrame.apply(data,normalize)
    

    从pandas的文档中,DataFrame结构可以将一个操作(函数)应用到自身。

    DataFrame.apply(func, axis=0, broadcast=False, raw=False, reduce=None, args=(), **kwds)
    

    传递给函数的对象是具有DataFrame索引(axis=0)或列(axis=1)索引的系列对象。返回类型取决于传递的函数是否聚合,如果数据帧为空,则取决于reduce参数。

    您可以应用自定义函数来操作数据帧。

        16
  •  2
  •   gogasca    5 年前

    def standardization(dataset):
      """ Standardization of numeric fields, where all values will have mean of zero 
      and standard deviation of one. (z-score)
    
      Args:
        dataset: A `Pandas.Dataframe` 
      """
      dtypes = list(zip(dataset.dtypes.index, map(str, dataset.dtypes)))
      # Normalize numeric columns.
      for column, dtype in dtypes:
          if dtype == 'float32':
              dataset[column] -= dataset[column].mean()
              dataset[column] /= dataset[column].std()
      return dataset
    
        17
  •  1
  •   antonjs    5 年前

    您只需使用转换.DataFrame.transform 1 功能如下:

    df.transform(lambda x: x/x.max())
    
        18
  •  0
  •   LOrD_ARaGOrN    5 年前

    你可以在一条线上完成

    DF_test = DF_test.sub(DF_test.mean(axis=0), axis=1)/DF_test.mean(axis=0)
    

    它取每一列的平均值,然后从每一行中减去它(平均值)(特定列的平均值仅从其行中减去),然后仅除以平均值。最后,我们得到的是标准化的数据集。

        19
  •  0
  •   ahajib Shaun McHugh    5 年前

    X= pd.read_csv('.\\data.csv')
    X = (X-X.min())/(X.max()-X.min())
    

    输出值将在0和1之间。

        20
  •  -2
  •   Adrian Mole Khaled Ali    4 年前

    如果您的数据是正倾斜的,那么规范化的最佳方法是使用日志转换:

    df = np.log10(df)