我在熊猫中有一个数据框,其中每一列都有不同的值范围。例如:
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)
ddof
争论吗?
我在熊猫中有一个数据框,其中每一列都有不同的值范围。例如:
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)
ddof
争论吗?
Answers:
您可以使用软件包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 文档:将特征缩放到一定范围。
pd.DataFrame(min_max_scaler.fit_transform(df.T), columns=df.columns, index=df.index)
使用Pandas的一种简单方法:(这里我要使用均值归一化)
normalized_df=(df-df.mean())/df.std()
使用最小-最大规格化:
normalized_df=(df-df.min())/(df.max()-df.min())
编辑:要解决一些问题,需要说熊猫自动在上面的代码中应用了以列为单位的函数。
根据这篇文章: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之间很好地分布。
您的问题实际上是作用在列上的简单转换:
def f(s):
return s/s.max()
frame.apply(f, axis=0)
或更简洁:
frame.apply(lambda x: x/x.max(), axis=0)
lambda
一个是最好的:-)
简单即美:
df["A"] = df["A"] / df["A"].max()
df["B"] = df["B"] / df["B"].max()
df["C"] = df["C"] / df["C"].max()
df["A"] = (df["A"]-df["A"].min()) / (df["A"].max()-df["A"].min())
df /= df.max()
-假设目标是分别标准化每个列。
您可以创建要标准化的列的列表
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
现在,您的Pandas Dataframe仅在您想要的列上进行了标准化
但是,如果你想的相反,选择列的列表不要想规范化,您可以简单地创建的所有列的列表,删除非期望的人
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 ]
Sandman和Praveen给出的解决方案非常好。唯一的问题是,如果数据框的其他列中有类别变量,则此方法将需要进行一些调整。
我针对此类问题的解决方案如下:
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])
python中不同标准化的示例。
作为参考,请参阅以下维基百科文章: https //en.wikipedia.org/wiki/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.preprocessing.scale的官方文档指出,使用偏倚估计量会异常地影响机器学习算法的性能,因此我们可以安全地使用它们。
From official documentation:
We use a biased estimator for the standard deviation,
equivalent to numpy.std(x, ddof=0).
Note that the choice of ddof is unlikely to affect model performance.
MinMax缩放中没有标准偏差计算。因此,在熊猫和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
您可能希望对某些列进行规范化,而对其他列进行不变,例如某些回归任务,其中数据标签或分类列不变,因此,我建议您使用这种pythonic方式(这是@shg和@Cina答案的组合):
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()))
def normalize(x):
try:
x = x/np.linalg.norm(x,ord=1)
return x
except :
raise
data = pd.DataFrame.apply(data,normalize)
从熊猫文件中,DataFrame结构可以对其自身应用操作(函数)。
DataFrame.apply(func, axis=0, broadcast=False, raw=False, reduce=None, args=(), **kwds)
沿DataFrame的输入轴应用功能。传递给函数的对象是Series对象,其索引为DataFrame的索引(axis = 0)或列(axis = 1)。返回类型取决于传递的函数是否聚合,或者取决于DataFrame为空时的reduce参数。
您可以应用自定义函数来操作DataFrame。
以下函数计算Z分数:
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
df_normalized = df / df.max(axis=0)
您可以一行完成
DF_test = DF_test.sub(DF_test.mean(axis=0), axis=1)/DF_test.mean(axis=0)
它对每一列取均值,然后从每一行中减去(均值)(特定列的均值仅从其行中减去)并仅除以均值。最后,我们得到的是标准化数据集。