web-dev-qa-db-fra.com

Comment utiliser sklearn fit_transform avec pandas et renvoyer dataframe au lieu du tableau numpy?

Je souhaite appliquer la mise à l'échelle (à l'aide de StandardScaler () à partir de sklearn.preprocessing) à un pandas dataframe. Le code suivant renvoie un tableau numpy, de sorte que je perds tous les noms de colonnes et les indeces. Ce n'est pas ce que je veux.

features = df[["col1", "col2", "col3", "col4"]]
autoscaler = StandardScaler()
features = autoscaler.fit_transform(features)

Une "solution" trouvée en ligne est:

features = features.apply(lambda x: autoscaler.fit_transform(x))

Cela semble fonctionner, mais conduit à un avertissement déconseillé:

/usr/lib/python3.5/site-packages/sklearn/preprocessing/data.py:583: DeprecationWarning: Le passage de tableaux 1d lorsque les données sont obsolètes en 0.17 et que ValueError est généré en 0.19. Modifiez la forme de vos données en utilisant X.reshape (-1, 1) si vos données ont une seule fonctionnalité ou X.reshape (1, -1) si elles contiennent un seul échantillon.

J'ai donc essayé:

features = features.apply(lambda x: autoscaler.fit_transform(x.reshape(-1, 1)))

Mais cela donne:

Traceback (appel le plus récent en dernier): Fichier "./analyse.py", ligne 91, dans features = features.apply (lambda x: autoscaler.fit_transform (x.reshape (-1, 1))) Fichier "/ usr/lib/python3.5/site-packages/pandas/core/frame.py ", ligne 3972, dans le fichier apply return self._apply_standard (f, axis, réduire = réduire) Fichier" /usr/lib/python3.5/site- packages/pandas/core/frame.py ", ligne 4081, dans _apply_standard resultat = self._constructor (données = résultats, index = index) Fichier" /usr/lib/python3.5/site-packages/pandas/core/frame .py ", ligne 226, dans init mgr = self._init_dict (data, index, colonnes, dtype = dtype) Fichier" /usr/lib/python3.5/site-packages/pandas/core /frame.py ", ligne 363, dans _init_dict dtype = dtype) Fichier" /usr/lib/python3.5/site-packages/pandas/core/frame.py ", ligne 5163, dans _arrays_to_mgr arrays = _homogenize (tableaux, index, dtype) Fichier "/usr/lib/python3.5/site-packages/pandas/core/frame.py", ligne 5477, dans _homogenize raise_cast_failure = False) Fichier "/usr/lib/python3.5/site- packages/pandas/core/series.py ", ligne 2885, à _san itize_array raise Exception ('Les données doivent être à une dimension') Exception: Les données doivent être à une dimension

Comment appliquer la mise à l'échelle à la dataframe pandas, en laissant la dataframe intacte? Sans copier les données si possible.

40
louic

Vous pouvez convertir le DataFrame sous forme de tableau numpy à l’aide de as_matrix() . Exemple sur un jeu de données aléatoire:

Edit: Modification de as_matrix() en values, (le résultat ne change pas) par la dernière phrase de la as_matrix() docs ci-dessus:

En règle générale, il est recommandé d’utiliser des "valeurs".

import pandas as pd
import numpy as np #for the random integer example
df = pd.DataFrame(np.random.randint(0.0,100.0,size=(10,4)),
              index=range(10,20),
              columns=['col1','col2','col3','col4'],
              dtype='float64')

Remarque, les indices sont 10-19:

In [14]: df.head(3)
Out[14]:
    col1    col2    col3    col4
    10  3   38  86  65
    11  98  3   66  68
    12  88  46  35  68

À présent fit_transform le DataFrame pour obtenir le scaled_featuresarray:

from sklearn.preprocessing import StandardScaler
scaled_features = StandardScaler().fit_transform(df.values)

In [15]: scaled_features[:3,:] #lost the indices
Out[15]:
array([[-1.89007341,  0.05636005,  1.74514417,  0.46669562],
       [ 1.26558518, -1.35264122,  0.82178747,  0.59282958],
       [ 0.93341059,  0.37841748, -0.60941542,  0.59282958]])

Affectez les données redimensionnées à un DataFrame (Remarque: utilisez les arguments de mot clé index et columns pour conserver vos index et noms de colonne d'origine:

scaled_features_df = pd.DataFrame(scaled_features, index=df.index, columns=df.columns)

In [17]:  scaled_features_df.head(3)
Out[17]:
    col1    col2    col3    col4
10  -1.890073   0.056360    1.745144    0.466696
11  1.265585    -1.352641   0.821787    0.592830
12  0.933411    0.378417    -0.609415   0.592830

Éditer 2:

Entré dans le paquet sklearn-pandas . Son objectif est de rendre l'utilisation de scikit-learn plus facile à utiliser avec des pandas. sklearn-pandas est particulièrement utile lorsque vous devez appliquer plusieurs types de transformation à des sous-ensembles de colonnes du DataFrame, un scénario plus courant. C'est documenté, mais c'est ainsi que vous réaliseriez la transformation que nous venons de réaliser.

from sklearn_pandas import DataFrameMapper

mapper = DataFrameMapper([(df.columns, StandardScaler())])
scaled_features = mapper.fit_transform(df.copy(), 4)
scaled_features_df = pd.DataFrame(scaled_features, index=df.index, columns=df.columns)
43
Kevin
import pandas as pd    
from sklearn.preprocessing import StandardScaler

df = pd.read_csv('your file here')
ss = StandardScaler()
df_scaled = pd.DataFrame(ss.fit_transform(df),columns = df.columns)

Le df_scaled sera le "même" dataframe, seulement maintenant avec les valeurs mises à l'échelle

6
Joe