7 votes

fillna : comment remplir les valeurs au cours des x prochains jours

J'ai un dataframe avec plusieurs colonnes et indexé par dates. J'aimerais remplir les valeurs manquantes, mais seulement pour les x jours suivants. Cela signifie qu'une valeur manquante ne sera pas remplie si sa différence d'index est supérieure à x jours par rapport à la valeur non manquante précédente dans cette colonne.

J'ai fait quelque chose avec une boucle mais ce n'est pas très efficace. Existe-t-il une meilleure méthode, plus élégante ?

Je précise que les dates de mon index ne sont pas espacées de la même manière, de sorte que l'argument de la limite ne fonctionnera pas.

7voto

Andy Hayden Points 38010

Vous pouvez utiliser le limit argument de fillna :

df.fillna(method='ffill', limit=3)  # ffill is equivalent to pad

Le même argument est disponible pour l'option ffill , bfill les fonctions de commodité.

limit : int , par défaut None
Taille maximale de l'espace pour le remplissage avant ou arrière

Si vos dates ne sont pas régulièrement espacées, vous pouvez resample (de jour) en premier :

df.resample('D')

_Voir aussi le données manquantes de la documentation._

1voto

Jeff Points 27612

Ceci illustre ce que je voulais dire

In [20]: df = DataFrame(randn(10,2),columns=list('AB'),index=date_range('20130101',periods=3)+date_range('20130110',periods=3)+date_range('20130120',periods=4))

In [21]: df
Out[21]: 
                   A         B
2013-01-01 -0.176354  1.033962
2013-01-02  0.666911 -0.018723
2013-01-03  0.300097  1.552866
2013-01-10  0.581816 -1.188106
2013-01-11 -0.394817 -1.018765
2013-01-12  1.000461 -1.211131
2013-01-20  0.097940  1.225805
2013-01-21 -2.205975 -0.455641
2013-01-22  0.508865 -0.403321
2013-01-23 -0.726969  0.448002

In [22]: df.reindex(index=date_range('20130101','20130125')).fillna(limit=2,method='pad')
Out[22]: 
                   A         B
2013-01-01 -0.176354  1.033962
2013-01-02  0.666911 -0.018723
2013-01-03  0.300097  1.552866
2013-01-04  0.300097  1.552866
2013-01-05  0.300097  1.552866
2013-01-06       NaN       NaN
2013-01-07       NaN       NaN
2013-01-08       NaN       NaN
2013-01-09       NaN       NaN
2013-01-10  0.581816 -1.188106
2013-01-11 -0.394817 -1.018765
2013-01-12  1.000461 -1.211131
2013-01-13  1.000461 -1.211131
2013-01-14  1.000461 -1.211131
2013-01-15       NaN       NaN
2013-01-16       NaN       NaN
2013-01-17       NaN       NaN
2013-01-18       NaN       NaN
2013-01-19       NaN       NaN
2013-01-20  0.097940  1.225805
2013-01-21 -2.205975 -0.455641
2013-01-22  0.508865 -0.403321
2013-01-23 -0.726969  0.448002
2013-01-24 -0.726969  0.448002
2013-01-25 -0.726969  0.448002

0voto

Maxi Points 545

En fait, je viens de penser à la solution. Il faudrait 3 lignes de code :

1/ rééchantillonner la base de données à la seconde près. 2/ remplir avec la limite 3/ réindexer mon nouveau dataframe avec l'index du dataframe original

En termes de vitesse, je ne sais pas à quoi cela ressemblera, mais je pense que cela devrait aller, car la plupart des fonctions pandas sont implémentées en Cython.

0voto

david.bew Points 1

Dans la veine de la réponse d'Onyxx, j'ai résolu le même problème de la manière suivante :

  1. Ajouter une colonne à la base de données pour la date d'indexation, fixée à nan où les données à remplir sont nan.
  2. Remplir la colonne de la date d'indexation et les données
  3. Fixer des nans lorsque la date d'indexation remplie est trop ancienne.

0voto

Maxi Points 545

J'ai résolu ce problème en implémentant une fonction Cython qui ferait le travail pour une série. J'appelle simplement cette fonction sur chaque colonne de mon dataframe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X