work with tutorial new index functions example data create python pandas dataframe subclassing

python - with - ¿Cómo subclase pandas DataFrame?



python pandas dataframe tutorial (2)

Subclasificar las clases de pandas parece ser una necesidad común, pero no pude encontrar referencias sobre el tema. (Parece que los desarrolladores de pandas todavía están trabajando en ello: https://github.com/pydata/pandas/issues/60 ).

Hay algunos subprocesos SO sobre el tema, pero espero que alguien aquí pueda proporcionar una explicación más sistemática sobre la mejor manera actual de crear subclases de pandas.DataFrame que satisfaga dos, creo, requisitos generales:

import numpy as np import pandas as pd class MyDF(pd.DataFrame): # how to subclass pandas DataFrame? pass mydf = MyDF(np.random.randn(3,4), columns=[''A'',''B'',''C'',''D'']) print type(mydf) # <class ''__main__.MyDF''> # Requirement 1: Instances of MyDF, when calling standard methods of DataFrame, # should produce instances of MyDF. mydf_sub = mydf[[''A'',''C'']] print type(mydf_sub) # <class ''pandas.core.frame.DataFrame''> # Requirement 2: Attributes attached to instances of MyDF, when calling standard # methods of DataFrame, should still attach to the output. mydf.myattr = 1 mydf_cp1 = MyDF(mydf) mydf_cp2 = mydf.copy() print hasattr(mydf_cp1, ''myattr'') # False print hasattr(mydf_cp2, ''myattr'') # False

¿Y hay diferencias significativas para la clasificación de pandas.Series? Gracias.


Ahora hay una guía oficial sobre cómo subclasificar estructuras de datos de Pandas, que incluye DataFrame y Series.

La guía está disponible aquí: here

La guía menciona este DataFrame subclasificado del proyecto Geopandas como un buen ejemplo: https://github.com/geopandas/geopandas/blob/master/geopandas/geodataframe.py

Como en la respuesta de HYRY, parece que hay dos cosas que estás tratando de lograr:

  1. Al llamar a métodos en una instancia de su clase, devuelva instancias del tipo correcto (su tipo). Para esto, simplemente puede agregar la propiedad _constructor que debería devolver su tipo.
  2. Agregando atributos que se adjuntarán a las copias de su objeto. Para hacer esto, necesita almacenar los nombres de estos atributos en una lista, como el atributo especial _metadata .

Aquí hay un ejemplo:

class SubclassedDataFrame(DataFrame): _metadata = [''added_property''] added_property = 1 # This will be passed to copies @property def _constructor(self): return SubclassedDataFrame


Para el Requisito 1, simplemente defina _constructor :

import pandas as pd import numpy as np class MyDF(pd.DataFrame): @property def _constructor(self): return MyDF mydf = MyDF(np.random.randn(3,4), columns=[''A'',''B'',''C'',''D'']) print type(mydf) mydf_sub = mydf[[''A'',''C'']] print type(mydf_sub)

Creo que no hay una solución simple para el Requisito 2, creo que necesita definir __init__ , copy o hacer algo en _constructor , por ejemplo:

import pandas as pd import numpy as np class MyDF(pd.DataFrame): _attributes_ = "myattr1,myattr2" def __init__(self, *args, **kw): super(MyDF, self).__init__(*args, **kw) if len(args) == 1 and isinstance(args[0], MyDF): args[0]._copy_attrs(self) def _copy_attrs(self, df): for attr in self._attributes_.split(","): df.__dict__[attr] = getattr(self, attr, None) @property def _constructor(self): def f(*args, **kw): df = MyDF(*args, **kw) self._copy_attrs(df) return df return f mydf = MyDF(np.random.randn(3,4), columns=[''A'',''B'',''C'',''D'']) print type(mydf) mydf_sub = mydf[[''A'',''C'']] print type(mydf_sub) mydf.myattr1 = 1 mydf_cp1 = MyDF(mydf) mydf_cp2 = mydf.copy() print mydf_cp1.myattr1, mydf_cp2.myattr1