2017-10-15 3 views
0

Je suis la sklearn_pandas marche à travers trouvé sur le sklearn_pandas README on github et essaie de modifier l'exemple du transformateur personnalisé DateEncoder() pour faire 2 choses supplémentaires:transformateur sur mesure qui divise les dates dans la nouvelle colonne

  • Convertir des colonnes de type chaîne à date/heure tout en prenant le format de date en paramètre
  • Ajoutez les noms de colonne d'origine lors du crachement des nouvelles colonnes. Par exemple: si colonne d'entrée: Date1 puis sorties: Date1_year, Date1_month, Date_1 jour.

Voici ma tentative (avec une compréhension assez rudimentaire des pipelines de sklearn):

import pandas as pd 
import numpy as np 
from sklearn.base import TransformerMixin, BaseEstimator 
from sklearn_pandas import DataFrameMapper 

class DateEncoder(TransformerMixin): 

    ''' 
    Specify date format using python strftime formats 
    ''' 

    def __init__(self, date_format='%Y-%m-%d'): 
     self.date_format = date_format 

    def fit(self, X, y=None): 
     self.dt = pd.to_datetime(X, format=self.date_format) 
     return self 

    def transform(self, X): 
     dt = X.dt 
     return pd.concat([dt.year, dt.month, dt.day], axis=1) 


data = pd.DataFrame({'dates1': ['2001-12-20','2002-10-21','2003-08-22','2004-08-23', 
           '2004-07-20','2007-12-21','2006-12-22','2003-04-23'], 
        'dates2' : ['2012-12-20','2009-10-21','2016-08-22','2017-08-23', 
           '2014-07-20','2011-12-21','2014-12-22','2015-04-23']}) 

DATE_COLS = ['dates1', 'dates2'] 

Mapper = DataFrameMapper([(i, DateEncoder(date_format='%Y-%m-%d')) for i in DATE_COLS], input_df=True, df_out=True) 
test = Mapper.fit_transform(data) 

Mais l'exécution, je reçois l'erreur suivante:

AttributeError: Can only use .dt accessor with datetimelike values 

Pourquoi est-ce que je reçois ce erreur et comment y remédier? De même, toute aide pour renommer les noms de colonnes comme mentionné ci-dessus avec les colonnes d'origine (Date1_year, Date1_month, Date_1 jour) serait grandement appréciée!

+0

Vous convertissez 'X' en datetime à' self.dt' dans 'fit', mais' transform() 'ne fonctionne pas avec' self.dt'. 'X.dt' échoue parce que' X' n'est pas de type datetime. –

Répondre

0

J'ai été capable de décomposer la conversion de format de données et le séparateur de date en deux transformateurs distincts et cela a fonctionné.

import pandas as pd 
from sklearn.base import TransformerMixin 
from sklearn_pandas import DataFrameMapper 



data2 = pd.DataFrame({'dates1': ['2001-12-20','2002-10-21','2003-08-22','2004-08-23', 
           '2004-07-20','2007-12-21','2006-12-22','2003-04-23'], 
        'dates2' : ['2012-12-20','2009-10-21','2016-08-22','2017-08-23', 
           '2014-07-20','2011-12-21','2014-12-22','2015-04-23']}) 

class DateFormatter(TransformerMixin): 

    def fit(self, X, y=None): 
     # stateless transformer 
     return self 

    def transform(self, X): 
     # assumes X is a DataFrame 
     Xdate = X.apply(pd.to_datetime) 
     return Xdate 


class DateEncoder(TransformerMixin): 

    def fit(self, X, y=None): 
     return self 

    def transform(self, X): 
     dt = X.dt 
     return pd.concat([dt.year, dt.month, dt.day], axis=1) 


DATE_COLS = ['dates1', 'dates2'] 

datemult = DataFrameMapper(
      [ (i,[DateFormatter(),DateEncoder()]) for i in DATE_COLS  ] 
      , input_df=True, df_out=True) 

df = datemult.fit_transform(data2) 

Ce sorties de code:

Out[4]: 
    dates1_0 dates1_1 dates1_2 dates2_0 dates2_1 dates2_2 
0  2001  12  20  2012  12  20 
1  2002  10  21  2009  10  21 
2  2003   8  22  2016   8  22 
3  2004   8  23  2017   8  23 
4  2004   7  20  2014   7  20 
5  2007  12  21  2011  12  21 
6  2006  12  22  2014  12  22 
7  2003   4  23  2015   4  23 

Cependant, je suis toujours à la recherche d'un moyen de renommer les nouvelles colonnes lors de l'application du transformateur DateEncoder(). E.g: dates_1_0 ->dates_1_year et dates_2_2 ->dates_2_month. Je serais heureux de choisir cela comme solution.