2012-08-16 10 views
5

Sto cercando di creare una sottoclasse di una struttura di dati Panda di sostituire, nel mio codice, una sottoclasse di un dict con una sottoclasse di un Series, non capisco il motivo per cui questo codice di esempio non funzionale sottoclassi degli oggetti dei panda funzionano diversamente dalla sottoclasse di altri oggetti?

from pandas import Series  

class Support(Series): 
    def supportMethod1(self): 
     print 'I am support method 1'  
    def supportMethod2(self): 
     print 'I am support method 2' 

class Compute(object): 
    supp=None   
    def test(self): 
     self.supp() 

class Config(object): 
    supp=None   
    @classmethod 
    def initializeConfig(cls): 
     cls.supp=Support() 
    @classmethod 
    def setConfig1(cls): 
     Compute.supp=cls.supp.supportMethod1 
    @classmethod 
    def setConfig2(cls): 
     Compute.supp=cls.supp.supportMethod2    

Config.initializeConfig() 

Config.setConfig1()  
c1=Compute() 
c1.test() 

Config.setConfig2()  
c1.test() 

Probabilmente non è il metodo migliore per modificare la configurazione di alcuni oggetti, in ogni caso ho trovato questo utile nel mio codice e la maggior parte di tutto voglio capire perché con dict invece di serie funziona come mi aspetto.

Grazie mille!

risposta

10

Risposta attuale (Pandas> = 0,13)

Un refactoring interno Pandas 0,13 sottoclassi drasticamente semplificata. Pandas Series possono ora essere sottoclasse come qualsiasi altro oggetto Python:

class MySeries(pd.Series): 
    def my_method(self): 
     return "my_method" 

legacy Risposta (pandi < = 0,12)

Il problema è che Series utilizza __new__ che è garantire che un oggetto è un'istanza serie.

È possibile modificare la classe in questo modo:

class Support(pd.Series): 
    def __new__(cls, *args, **kwargs): 
     arr = Series.__new__(cls, *args, **kwargs) 
     return arr.view(Support) 

    def supportMethod1(self): 
     print 'I am support method 1'  
    def supportMethod2(self): 
     print 'I am support method 2' 

Tuttavia, è probabilmente meglio per fare un has-a invece di un is-a. O scimmietta l'oggetto Series. Il motivo è che spesso perdi la sottoclasse mentre usi i panda a causa della natura della sua memoria dati. Qualcosa di semplice come

s.ix[:5] 
s.cumsum() 

Restituirà un oggetto Serie invece della sottoclasse. Internamente, i dati vengono archiviati in array contigui e ottimizzati per la velocità. I dati sono solo classificati con una classe quando necessario e quelle classi sono codificate. Inoltre, non è immediatamente evidente se qualcosa come s.ix[:5] debba restituire la stessa sottoclasse. Ciò dipenderebbe dalla semantica della sottoclasse e da quali metadati sono collegati ad essa.

http://nbviewer.ipython.org/3366583/subclassing%20pandas%20objects.ipynb ha alcune note.

+0

funziona! Ma hai ragione ... probabilmente non è stata la scelta migliore per implementare una sottoclasse! Grazie mille !!! – Francesco

2

Support() restituisce un oggetto Series.

Su sottoclassi di serie e dataframe vedi anche: https://github.com/pydata/pandas/issues/60

In [16]: class MyDict(dict): 
    ....:  pass 
    ....: 

In [17]: md = MyDict() 

In [18]: type(md) 
Out[18]: __main__.MyDict 

In [21]: class MySeries(Series): 
    ....:  pass 
    ....: 

In [22]: ms = MySeries() 

In [23]: type(ms) 
Out[23]: pandas.core.series.Series 
Problemi correlati