Je suis ignorant le warnings et essayant de sous-classer un DataFrame pandas. Mes raisons pour le faire sont les suivantes:Pourquoi le sous-classement d'un objet DataFrame fait-il muter l'objet d'origine?
- Je veux conserver toutes les méthodes existantes de
DataFrame
. - Je veux définir quelques attributs supplémentaires à l'instanciation de classe, qui sera plus tard utilisée pour définir des méthodes supplémentaires que je peux appeler sur la sous-classe.
Voici un extrait:
class SubFrame(pd.DataFrame):
def __init__(self, *args, **kwargs):
freq = kwargs.pop('freq', None)
ddof = kwargs.pop('ddof', None)
super(SubFrame, self).__init__(*args, **kwargs)
self.freq = freq
self.ddof = ddof
self.index.freq = pd.tseries.frequencies.to_offset(self.freq)
@property
def _constructor(self):
return SubFrame
Voici un exemple d'utilisation. Dire que j'ai le DataFrame
print(df)
col0 col1 col2
2014-07-31 0.28393 1.84587 -1.37899
2014-08-31 5.71914 2.19755 3.97959
2014-09-30 -3.16015 -7.47063 -1.40869
2014-10-31 5.08850 1.14998 2.43273
2014-11-30 1.89474 -1.08953 2.67830
où l'indice n'a pas de fréquence
print(df.index)
DatetimeIndex(['2014-07-31', '2014-08-31', '2014-09-30', '2014-10-31',
'2014-11-30'],
dtype='datetime64[ns]', freq=None)
En utilisant SubFrame
me permet de spécifier que la fréquence en une seule étape:
sf = SubFrame(df, freq='M')
print(sf.index)
DatetimeIndex(['2014-07-31', '2014-08-31', '2014-09-30', '2014-10-31',
'2014-11-30'],
dtype='datetime64[ns]', freq='M')
La question est, ce modifie df
:
print(df.index.freq)
<MonthEnd>
Que se passe-t-il ici, et comment puis-je éviter cela?
En outre, je prétends utiliser le code copied que je ne comprends pas très bien. Que se passe-t-il dans __init__
ci-dessus? Est-il nécessaire d'utiliser args/kwargs avec pop
ici? (Pourquoi ne puis-je pas simplement spécifier les paramètres comme d'habitude?)
Le cas d'utilisation typique pour subclassing est de modifier/étendre la fonctionnalité de la classe de base d'une manière ou d'une autre. Tu ne fais pas vraiment ça ici. Vous configurez simplement votre DataFrame d'une manière spécifique. Plutôt que de sous-classer, vous pouvez simplement créer une fonction/un objet de type usine qui renvoie simplement un DataFrame construit comme vous le souhaitez. Le sous-classement ne semble pas avoir beaucoup de sens pour ce cas particulier. – clockwatcher
"créer une fonction/objet de type usine qui retourne simplement un DataFrame construit comme vous le souhaitez." Pouvez-vous élaborer sur cela s'il vous plaît? En ce moment, j'ai un 'Class (object)' standard où la dataframe est un attribut. Et oui, j'étends la fonctionnalité en définissant plus d'une poignée d'autres méthodes, non montrées ici. –
Regardez la deuxième suggestion de piRSquared avec le tuyau. Notez qu'il ne sous-classe pas. Il crée une fonction qui renvoie simplement un DataFrame comme vous le souhaitez. Il n'y a pas besoin de sous-classe. Vous ne changez pas de comportement. Une des utilisations d'une classe d'usine est de créer l'objet mis en place comme vous le souhaitez. Si vous souhaitez baser un nouveau DataFrame sur une copie de la première, vous devez créer une fonction qui prend en paramètre le DataFrame existant, le copie, ajoute votre fréquence et renvoie la copie. Aucune sous-classe. – clockwatcher