Je veux utiliser le sklearn
de StandardScaler
. Est-il possible de l'appliquer à certaines colonnes d'entités mais pas à d'autres?
Par exemple, disons que mon data
est:
data = pd.DataFrame({'Name' : [3, 4,6], 'Age' : [18, 92,98], 'Weight' : [68, 59,49]})
Age Name Weight
0 18 3 68
1 92 4 59
2 98 6 49
col_names = ['Name', 'Age', 'Weight']
features = data[col_names]
J'ajuste et transforme le data
scaler = StandardScaler().fit(features.values)
features = scaler.transform(features.values)
scaled_features = pd.DataFrame(features, columns = col_names)
Name Age Weight
0 -1.069045 -1.411004 1.202703
1 -0.267261 0.623041 0.042954
2 1.336306 0.787964 -1.245657
Mais bien sûr, les noms ne sont pas vraiment des entiers mais des chaînes et je ne veux pas les normaliser. Comment appliquer les méthodes fit
et transform
uniquement sur les colonnes Age
et Weight
?
Actuellement, la meilleure façon de gérer cela est d'utiliser ColumnTransformer comme expliqué ici .
Créez d'abord une copie de votre dataframe:
scaled_features = data.copy()
N'incluez pas la colonne Nom dans la transformation:
col_names = ['Age', 'Weight']
features = scaled_features[col_names]
scaler = StandardScaler().fit(features.values)
features = scaler.transform(features.values)
Maintenant, ne créez pas de nouvelle trame de données mais affectez le résultat à ces deux colonnes:
scaled_features[col_names] = features
print(scaled_features)
Age Name Weight
0 -1.411004 3 1.202703
1 0.623041 4 0.042954
2 0.787964 6 -1.245657
Introduit dans la v0.20 est ColumnTransformer qui applique des transformateurs à un ensemble spécifié de colonnes d'un tableau ou pandas DataFrame.
import pandas as pd
data = pd.DataFrame({'Name' : [3, 4,6], 'Age' : [18, 92,98], 'Weight' : [68, 59,49]})
col_names = ['Name', 'Age', 'Weight']
features = data[col_names]
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler
ct = ColumnTransformer([
('somename', StandardScaler(), ['Age', 'Weight'])
], remainder='passthrough')
ct.fit_transform(features)
NB: Comme Pipeline, il a également une version abrégée make_column_transformer qui ne nécessite pas de nommer les transformateurs
-1.41100443, 1.20270298, 3.
0.62304092, 0.04295368, 4.
0.78796352, -1.24565666, 6.
Une autre option serait de supprimer la colonne Nom avant la mise à l'échelle, puis de la fusionner à nouveau:
data = pd.DataFrame({'Name' : [3, 4,6], 'Age' : [18, 92,98], 'Weight' : [68, 59,49]})
from sklearn.preprocessing import StandardScaler
# Save the variable you don't want to scale
name_var = data['Name']
# Fit scaler to your data
scaler.fit(data.drop('Name', axis = 1))
# Calculate scaled values and store them in a separate object
scaled_values = scaler.transform(data.drop('Name', axis = 1))
data = pd.DataFrame(scaled_values, index = data.index, columns = data.drop('ID', axis = 1).columns)
data['Name'] = name_var
print(data)
Une façon plus pythonique de le faire -
from sklearn.preprocessing import StandardScaler
data[['Age','Weight']] = data[['Age','Weight']].apply(
lambda x: StandardScaler().fit_transform(x))
data
Production -
Age Name Weight
0 -1.411004 3 1.202703
1 0.623041 4 0.042954
2 0.787964 6 -1.245657