标准化数据框的列
我在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的文档,里面有关于数据预处理和特征缩放的内容。