1
votes

Calcul de la moyenne de quelques valeurs dans une trame de données pour remplir les valeurs NaN dans la même colonne

J'ai un dataframe où les données progressent à des intervalles d'une heure mais l'une des colonnes a quelques valeurs NaN. Lorsque je rencontre un NaN, je voudrais que le code fasse la moyenne des quatre heures avant le NaN, puis remplace le NaN par cette moyenne.

Je suis fatigué de modifier la réponse à cette question: pandas DataFrame : remplacez les valeurs nan par la moyenne des colonnes mais cet exemple prend une moyenne de la colonne entière et non d'une partie de la colonne.

My Dataframe:

for i in df.index:
    df[6].fillna(df[6].iloc[0:3].mean(), inplace=True)


2 commentaires

Que faire s'il n'y a pas quatre lignes précédentes pour un NaN? Que faire s'il y a des NaN dans l'une des quatre lignes précédentes? Avez-vous réfléchi à cela?


C'est une excellente question. Je n'avais pas encore rencontré de NaN dans les dernières lignes, donc je n'y suis pas arrivé. Je pense que je prendrais alors une moyenne des quatre heures après le NaN si cela se produit dans l'une des dernières lignes. Mais s'il y a plusieurs NaN dos à dos, je suis à nouveau en difficulté.


3 Réponses :


1
votes

Cela devrait fonctionner? Je ne sais pas si quelque chose est déjà intégré aux pandas. J'ai dû ignorer les cas où il n'y avait pas de 4 lignes précédentes.

for i in df.index:
    if i < 4:
        pass
    else:
        df['6'].fillna(df.iloc[i-4:i,5].mean(), inplace=True)

Notez qu'il semble que votre colonne '6' ait en fait l'index 5, c'est pourquoi iloc utilise 5 pour la colonne. P >


0 commentaires

3
votes

Vous pouvez utiliser rolling avec la fenêtre de n pour obtenir la moyenne mobile des indices n précédents, puis remplir votre na avec ceux-ci valeurs:

    col1    rollmean5
0   1.0     1.00
1   2.0     1.50
2   3.0     2.00
3   4.0     2.50
4   5.0     3.00
5   6.0     4.00
6   4.5     4.50
7   8.0     5.75
8   9.0     7.00
9   10.0    8.25

L'utilisation d'une fenêtre glissante de 5 permet d'obtenir la moyenne de l'index actuel et du précédent 4.

Résultat:

df = pd.DataFrame({'col1':[1,2,3,4,5,6,np.nan,8,9,10]})
df['rollmean5'] = df['col1'].rolling(5,center=False,min_periods=1).mean()
df['col1'] = df['col1'].fillna(df['rollmean5'])


0 commentaires

0
votes

L'utilisation du code fourni par Joe Patten ci-dessus fonctionnait très bien jusqu'à ce que j'aie un NaN dans la ligne supérieure de la colonne. Pour résoudre cela, je vérifie si la première valeur est NaN, si c'est le cas, j'inverse la trame de données et j'exécute une moyenne mobile à partir de ce qui était de bas en haut, puis je me réoriente vers la position correcte. Si la première valeur n'est pas un NaN, exécutez le code de moyenne mobile.

if df.isnull().loc[3,6] == 'True':
    df['rollmean5'] = df[6].loc[::-1].rolling(5,center=False,min_periods=1).mean()
    df['rollmean5'] = df['rollmean5'].loc[::-1]
    df[6] = df[6].fillna(round(df['rollmean5'],2))
else:
    df['rollmean5'] = df[6].rolling(5,center=False,min_periods=1).mean()
    df[6] = df[6].fillna(round(df['rollmean5'],2))


0 commentaires