标准化数据框的列

473 投票
24 回答
1046019 浏览
提问于 2025-04-28 01:06

我在pandas中有一个数据框(dataframe),每一列的数值范围都不一样。比如说:

数据框内容:

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)
暂无标签

24 个回答

65

你的问题其实就是对列进行一个简单的转换:

def f(s):
    return s/s.max()

frame.apply(f, axis=0)

或者可以更简洁一些:

   frame.apply(lambda x: x/x.max(), axis=0)
79

根据这篇文章: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之间。

89

规范化方法的详细示例

  • Pandas 规范化(无偏估计)
  • Sklearn 规范化(有偏估计)
  • 有偏和无偏对机器学习有影响吗?
  • 最小-最大缩放

参考资料: 维基百科:无偏标准差估计

示例数据

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

使用 pandas 进行规范化(提供无偏估计)

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

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 进行规范化(提供有偏估计,与 pandas 不同)

如果你用 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 不太可能影响模型性能。

那最小-最大缩放呢?

在最小-最大缩放中没有标准差的计算。所以在 pandas 和 scikit-learn 中结果是一样的。

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
810

有一种简单的方法可以使用Pandas库:(在这里我想用均值归一化)

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

如果想使用最小-最大归一化,可以这样做:

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

补充说明:为了回应一些疑问,需要说明的是,Pandas会自动对上面代码中的每一列应用相应的函数。

421

你可以使用一个叫做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)

想了解更多信息,可以查看scikit-learn的文档,里面有关于数据预处理和特征缩放的内容。

撰写回答