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
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
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
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))
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))
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))
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))
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:
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/
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).