我在pandas中有一个数据框,其中每列具有不同的值范围。例如:
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)
答案 0 :(得分:230)
使用 Pandas 的一种简单方法:(这里我想使用均值标准化)
normalized_df=(df-df.mean())/df.std()
使用min-max规范化:
normalized_df=(df-df.min())/(df.max()-df.min())
答案 1 :(得分:123)
您可以使用sklearn包及其关联的预处理实用程序来规范化数据。
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 = pandas.DataFrame(x_scaled)
有关更多信息,请查看关于预处理数据的scikit-learn documentation:将功能扩展到范围。
答案 2 :(得分:37)
根据这篇文章: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之间。
答案 3 :(得分:23)
如果您喜欢使用sklearn软件包,可以使用pandas loc
来保留列名和索引名称,如下所示:
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
scaled_values = scaler.fit_transform(df)
df.loc[:,:] = scaled_values
答案 4 :(得分:18)
您的问题实际上是对列进行简单的转换:
def f(s):
return s/s.max()
frame.apply(f, axis=0)
甚至更简洁:
frame.apply(lambda x: x/x.max(), axis=0)
答案 5 :(得分:16)
简单就是美丽:
df["A"] = df["A"] / df["A"].max()
df["B"] = df["B"] / df["B"].max()
df["C"] = df["C"] / df["C"].max()
答案 6 :(得分:12)
您可以创建要标准化的列的列表
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数据框现在仅在您想要的列上被标准化
但是,如果要相反,请选择不要标准化的列列表,只需创建所有列的列表,然后删除不需要的列
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 :(得分:8)
我认为在熊猫中更好的方法就是
df = df/df.max().astype(np.float64)
修改如果您的数据框中存在负数,则应使用
df = df/df.loc[df.abs().idxmax()].astype(np.float64)
答案 8 :(得分:6)
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])
答案 9 :(得分:4)
这只是简单的数学。答案应如下所示。
normed_df = (df - df.min()) / (df.max() - df.min())
答案 10 :(得分:3)
df_normalized = df / df.max(axis=0)
答案 11 :(得分:2)
您可能希望对某些列进行规范化,而对其他列保持不变,例如某些回归任务,其中数据标签或分类列不变,因此,我建议您使用这种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()))
答案 12 :(得分:1)
以下函数计算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
答案 13 :(得分:1)
您可以通过以下方式简单地使用pandas.DataFrame.transform 1函数:
Sheet1Button1
答案 14 :(得分:1)
这是您使用列表理解来按列进行操作的方式:
[df[col].update((df[col] - df[col].min()) / (df[col].max() - df[col].min())) for col in df.columns]
答案 15 :(得分:1)
请注意,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
归一化时,我们只需减去平均值并除以标准差即可。
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的官方文档,使用偏倚估计量会影响机器学习算法的性能,因此我们可以放心使用它们。
答案 16 :(得分:1)
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的输入轴应用功能。 传递给函数的对象是具有索引的系列对象,索引是DataFrame的索引(轴= 0)或列(轴= 1)。返回类型取决于是否传递函数聚合,如果DataFrame为空,则取决于reduce参数。
您可以应用自定义函数来操作DataFrame。
答案 17 :(得分:0)
您可以一行完成
DF_test = DF_test.sub(DF_test.mean(axis=0), axis=1)/DF_test.mean(axis=0)
对每一列取均值,然后从每一行中减去(均值)(特定列的均值仅从其行中减去)并仅除以均值。最后,我们得到的是归一化的数据集。
答案 18 :(得分:0)
Pandas默认情况下按列进行归一化。尝试下面的代码。
X= pd.read_csv('.\\data.csv')
X = (X-X.min())/(X.max()-X.min())
输出值将在0到1的范围内。
答案 19 :(得分:0)
嘿,使用带有 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))
答案 20 :(得分:-2)
如果您的数据存在正偏,则标准化的最佳方法是使用对数转换:
df = np.log10(df)