web-dev-qa-db-fra.com

Valeurs manquantes dans les séries chronologiques dans python

J'ai une trame de données de série chronologique, la trame de données est assez grande et contient des valeurs manquantes dans les 2 colonnes ('Humidité' et 'Pression'). Je voudrais imputer ces valeurs manquantes de manière intelligente, par exemple en utilisant la valeur du plus proche voisin ou la moyenne de l'horodatage précédent et suivant.Y a-t-il un moyen simple de le faire? J'ai essayé avec fancyimpute mais le jeu de données contient environ 180000 exemples et donne une erreur de mémoire enter image description here

9
Marco Miglionico

Considérez interpolate ( documentation ). Cet exemple montre comment combler les lacunes de n'importe quelle taille avec une ligne droite:

df = pd.DataFrame({'date': pd.date_range(start='2013-01-01', periods=10, freq='H'), 'value': range(10)})
df.loc[2:3, 'value'] = np.nan
df.loc[6, 'value'] = np.nan
df
                 date  value
0 2013-01-01 00:00:00    0.0
1 2013-01-01 01:00:00    1.0
2 2013-01-01 02:00:00    NaN
3 2013-01-01 03:00:00    NaN
4 2013-01-01 04:00:00    4.0
5 2013-01-01 05:00:00    5.0
6 2013-01-01 06:00:00    NaN
7 2013-01-01 07:00:00    7.0
8 2013-01-01 08:00:00    8.0
9 2013-01-01 09:00:00    9.0

df['value'].interpolate(method='linear', inplace=True)
                 date  value
0 2013-01-01 00:00:00    0.0
1 2013-01-01 01:00:00    1.0
2 2013-01-01 02:00:00    2.0
3 2013-01-01 03:00:00    3.0
4 2013-01-01 04:00:00    4.0
5 2013-01-01 05:00:00    5.0
6 2013-01-01 06:00:00    6.0
7 2013-01-01 07:00:00    7.0
8 2013-01-01 08:00:00    8.0
9 2013-01-01 09:00:00    9.0
7
Peter Leimbigler

Vous pouvez utiliser rolling comme ceci:

frame = pd.DataFrame({'Humidity':np.arange(50,64)})

frame.loc[[3,7,10,11],'Humidity'] = np.nan

frame.Humidity.fillna(frame.Humidity.rolling(4,min_periods=1).mean())

Production:

0     50.0
1     51.0
2     52.0
3     51.0
4     54.0
5     55.0
6     56.0
7     55.0
8     58.0
9     59.0
10    58.5
11    58.5
12    62.0
13    63.0
Name: Humidity, dtype: float64
3
Scott Boston

Interpoler et Filna:

Puisqu'il s'agit d'une question de série chronologique, j'utiliserai des images de graphique o/p dans la réponse à des fins d'explication:

Considérez que nous avons des données de séries chronologiques comme suit: (sur l'axe des x = nombre de jours, y = quantité)

pdDataFrame.set_index('Dates')['QUANTITY'].plot(figsize = (16,6))

enter image description here

Nous pouvons voir qu'il existe des données NaN dans les séries chronologiques. % de nan = 19,400% des données totales. Maintenant, nous voulons imputer des valeurs nulles/nan.

Je vais essayer de vous montrer o/p des méthodes d'interpolation et de filna pour remplir les valeurs Nan dans les données.

interpoler ():

Nous utiliserons d'abord l'interpolation:

pdDataFrame.set_index('Dates')['QUANTITY'].interpolate(method='linear').plot(figsize = (16,6))

enter image description here

REMARQUE: Il n'y a pas de méthode temporelle dans l'interpolation ici

fillna () avec méthode de remblayage

pdDataFrame.set_index('Dates')['QUANTITY'].fillna(value=None, method='backfill', axis=None, limit=None, downcast=None).plot(figsize = (16,6))

enter image description here

fillna () avec méthode de remblayage et limite = 7

limite: il s'agit du nombre maximum de valeurs NaN consécutives à remplir vers l'avant/vers l'arrière. En d'autres termes, s'il existe un écart avec plus de ce nombre de NaN consécutifs, il ne sera que partiellement comblé.

pdDataFrame.set_index('Dates')['QUANTITY'].fillna(value=None, method='backfill', axis=None, limit=7, downcast=None).plot(figsize = (16,6))

enter image description here

Je trouve la fonction fillna plus utile. Mais vous pouvez utiliser l'une des méthodes pour remplir les valeurs nan dans les deux colonnes.

Pour plus de détails sur ces fonctions, reportez-vous aux liens suivants:

  1. Filna: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.fillna.html#pandas.Series.fillna
  2. https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.interpolate.html

Il y a une autre Lib: impyute que vous pouvez consulter. Pour plus de détails concernant cette bibliothèque, référez-vous à ce lien: https://pypi.org/project/impyute/

1
Yogesh

On dirait que vos données sont par heure. Que diriez-vous de simplement prendre la moyenne de l'heure avant et de l'heure suivante? Ou changer la taille de la fenêtre à 2, ce qui signifie la moyenne de deux heures avant et après?

L'imputation à l'aide d'autres variables peut être coûteuse et vous ne devriez envisager ces méthodes que si les méthodes factices ne fonctionnent pas bien (par exemple, en introduisant trop de bruit).

0
Ray