web-dev-qa-db-fra.com

Appliquer StandardScaler à des parties d'un ensemble de données

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?

12
mitsi

Mettre à jour:

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
19
ayhan

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

Production

-1.41100443,  1.20270298,  3.       
 0.62304092,  0.04295368,  4.       
 0.78796352, -1.24565666,  6.       
12
Guy C

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)
1
Danil

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
0
hashcode55