我有一个熊猫的数据框架,其中每一列都有不同的值范围。例如:
df:
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)
我有一个熊猫的数据框架,其中每一列都有不同的值范围。例如:
df:
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)
当前回答
归一化方法的详细示例
熊猫正常化(无偏) Sklearn归一化(有偏) 有偏见vs无偏见会影响机器学习吗? Mix-max扩展
引用: 维基百科:标准偏差的无偏估计
示例数据
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进行标准化(给出有偏差的估计,与熊猫不同)
如果你用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有偏见的估计会降低机器学习的能力吗?
NO.
sklearn.预处理.scale的官方文档指出,使用偏估计器不太可能影响机器学习算法的性能,我们可以安全地使用它们。
来自官方文件:
我们对标准偏差使用一个有偏估计器,相当于numpy。性病(x, ddof = 0)。注意ddof的选择不太可能影响模型性能。
那MinMax Scaling呢?
在最小最大值缩放中没有标准偏差计算。所以熊猫和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
其他回答
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的索引(轴=0)或列(轴=1)索引的Series对象。返回类型取决于传递的函数是否聚合,如果DataFrame为空则使用reduce参数。
您可以应用自定义函数来操作DataFrame。
使用Pandas的一个简单方法:(这里我想使用均值归一化)
normalized_df=(df-df.mean())/df.std()
使用最小-最大归一化:
normalized_df=(df-df.min())/(df.max()-df.min())
编辑:为了解决一些问题,需要说明Pandas在上面的代码中自动应用列函数。
嘿,使用带有lambda的apply函数来加速这个过程:
def normalize(df_col):
# Condition to exclude 'ID' and 'Class' feature
if (str(df_col.name) != str('ID') and str(df_col.name)!=str('Class')):
max_value = df_col.max()
min_value = df_col.min()
#It avoids NaN and return 0 instead
if max_value == min_value:
return 0
sub_value = max_value - min_value
return np.divide(np.subtract(df_col,min_value),sub_value)
else:
return df_col
df_normalize = df.apply(lambda x :normalize(x))
注意这个答案,因为它只适用于范围为[0,n]的数据。这对任何范围的数据都不起作用。
简单就是美:
df["A"] = df["A"] / df["A"].max()
df["B"] = df["B"] / df["B"].max()
df["C"] = df["C"] / df["C"].max()
正常化
您可以使用minmax_scale将每一列转换为从0到1的刻度。
from sklearn.preprocessing import minmax_scale
df[:] = minmax_scale(df)
标准化
您可以使用比例将每列居中到平均值,并缩放到单位方差。
from sklearn.preprocessing import scale
df[:] = scale(df)
列的子集
归一化单列
from sklearn.preprocessing import minmax_scale
df['a'] = minmax_scale(df['a'])
只归一化数值列
import numpy as np
from sklearn.preprocessing import minmax_scale
cols = df.select_dtypes(np.number).columns
df[cols] = minmax_scale(df[cols])
完整的示例
# Prep
import pandas as pd
import numpy as np
from sklearn.preprocessing import minmax_scale
# Sample data
df = pd.DataFrame({'a':[0,1,2], 'b':[-10,-30,-50], 'c':['x', 'y', 'z']})
# MinMax normalize all numeric columns
cols = df.select_dtypes(np.number).columns
df[cols] = minmax_scale(df[cols])
# Result
print(df)
# a b c
# 0 0.0 1.0 x
# 2 0.5 0.5 y
# 3 1.0 0.0 z
注:
在所有示例中,可以使用scale来代替minmax_scale。保持索引、列名或非数值变量不变。函数应用于每一列。
警告:
对于机器学习,可以使用minmax_scale或train_test_split后的scale来避免数据泄露。
Info
更多关于标准化和规范化的信息:
https://machinelearningmastery.com/standardscaler-and-minmaxscaler-transforms-in-python/ https://en.wikipedia.org/wiki/Normalization_(统计) https://scikit-learn.org/stable/modules/classes.html#module-sklearn.preprocessing