63 votes

Moyenne glissante sur pandas sur une colonne spécifique

J'ai un cadre de données comme celui-ci qui est importé d'un CSV.

              stock  pop
Date
2016-01-04  325.316   82
2016-01-11  320.036   83
2016-01-18  299.169   79
2016-01-25  296.579   84
2016-02-01  295.334   82
2016-02-08  309.777   81
2016-02-15  317.397   75
2016-02-22  328.005   80
2016-02-29  315.504   81
2016-03-07  328.802   81
2016-03-14  339.559   86
2016-03-21  352.160   82
2016-03-28  348.773   84
2016-04-04  346.482   83
2016-04-11  346.980   80
2016-04-18  357.140   75
2016-04-25  357.439   77
2016-05-02  356.443   78
2016-05-09  365.158   78
2016-05-16  352.160   72
2016-05-23  344.540   74
2016-05-30  354.998   81
2016-06-06  347.428   77
2016-06-13  341.053   78
2016-06-20  363.515   80
2016-06-27  349.669   80
2016-07-04  371.583   82
2016-07-11  358.335   81
2016-07-18  362.021   79
2016-07-25  368.844   77
...             ...  ...

Je voulais ajouter une nouvelle colonne MA qui calcule la moyenne de roulement pour la colonne pop. J'ai essayé ce qui suit

df['MA']=data.rolling(5,on='pop').mean()

Je reçois une erreur

ValueError: Wrong number of items passed 2, placement implies 1

Je me suis donc dit que j'allais essayer de voir si cela fonctionnait sans ajouter de colonne. J'ai utilisé

 data.rolling(5,on='pop').mean()

J'ai obtenu le résultat suivant

               stock  pop
Date
2016-01-04       NaN   82
2016-01-11       NaN   83
2016-01-18       NaN   79
2016-01-25       NaN   84
2016-02-01  307.2868   82
2016-02-08  304.1790   81
2016-02-15  303.6512   75
2016-02-22  309.4184   80
2016-02-29  313.2034   81
2016-03-07  319.8970   81
2016-03-14  325.8534   86
2016-03-21  332.8060   82
2016-03-28  336.9596   84
2016-04-04  343.1552   83
2016-04-11  346.7908   80
2016-04-18  350.3070   75
2016-04-25  351.3628   77
2016-05-02  352.8968   78
2016-05-09  356.6320   78
2016-05-16  357.6680   72
2016-05-23  355.1480   74
2016-05-30  354.6598   81
2016-06-06  352.8568   77
2016-06-13  348.0358   78
2016-06-20  350.3068   80
2016-06-27  351.3326   80
2016-07-04  354.6496   82
2016-07-11  356.8310   81
2016-07-18  361.0246   79
2016-07-25  362.0904   77
...              ...  ...

Je n'arrive pas à appliquer la moyenne de Rolling sur la colonne pop. Qu'est-ce que je fais de mal ?

0 votes

Donne seulement ceci >>> data.rolling(5,on='pop') Rolling [window=5,center=False,axis=0,on=pop]

0 votes

Vous avez un saut de ligne entre les titres date y pop y stock . Quels sont les résultats de list(df) ?

2 votes

Utilisez ce data['pop'].rolling(5).mean() ...

87voto

Andrew L Points 3203

Pour assigner une colonne, vous pouvez créer un objet roulant basé sur votre Series :

df['new_col'] = data['column'].rolling(5).mean()

La réponse postée par ac2001 n'est pas la manière la plus performante de le faire. Il calcule une moyenne mobile sur chaque colonne du cadre de données, puis il affecte la colonne "ma" à l'aide de la colonne "pop". La première méthode de ce qui suit est beaucoup plus efficace :

%timeit df['ma'] = data['pop'].rolling(5).mean()
%timeit df['ma_2'] = data.rolling(5).mean()['pop']

1000 loops, best of 3: 497 µs per loop
100 loops, best of 3: 2.6 ms per loop

Je ne recommanderais pas d'utiliser la deuxième méthode, sauf si vous avez besoin de stocker des moyennes mobiles calculées sur toutes les autres colonnes.

0 votes

Que faire si je veux appliquer la moyenne mobile séparément en fonction des valeurs des autres colonnes ? Par exemple, si j'ai une colonne "type", je veux calculer la moyenne mobile séparément pour chaque type différent, c'est-à-dire la remettre à 0 pour chaque type. En fait, j'ai plusieurs colonnes dont je dois tenir compte.

13voto

Chuck Points 1564

Edit : pd.rolling_mean est déprécié dans pandas et sera supprimé à l'avenir. Au lieu de cela : Utilisation de pd.rolling vous pouvez faire :

df['MA'] = df['pop'].rolling(window=5,center=False).mean()

pour un cadre de données df :

          Date    stock  pop
0   2016-01-04  325.316   82
1   2016-01-11  320.036   83
2   2016-01-18  299.169   79
3   2016-01-25  296.579   84
4   2016-02-01  295.334   82
5   2016-02-08  309.777   81
6   2016-02-15  317.397   75
7   2016-02-22  328.005   80
8   2016-02-29  315.504   81
9   2016-03-07  328.802   81

Pour obtenir :

          Date    stock  pop    MA
0   2016-01-04  325.316   82   NaN
1   2016-01-11  320.036   83   NaN
2   2016-01-18  299.169   79   NaN
3   2016-01-25  296.579   84   NaN
4   2016-02-01  295.334   82  82.0
5   2016-02-08  309.777   81  81.8
6   2016-02-15  317.397   75  80.2
7   2016-02-22  328.005   80  80.4
8   2016-02-29  315.504   81  79.8
9   2016-03-07  328.802   81  79.6

Documentation : http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.rolling.html

Ancien : Bien qu'il soit déprécié, vous pouvez utiliser :

df['MA']=pd.rolling_mean(df['pop'], window=5)

pour obtenir :

          Date    stock  pop    MA
0   2016-01-04  325.316   82   NaN
1   2016-01-11  320.036   83   NaN
2   2016-01-18  299.169   79   NaN
3   2016-01-25  296.579   84   NaN
4   2016-02-01  295.334   82  82.0
5   2016-02-08  309.777   81  81.8
6   2016-02-15  317.397   75  80.2
7   2016-02-22  328.005   80  80.4
8   2016-02-29  315.504   81  79.8
9   2016-03-07  328.802   81  79.6

Documentation : http://pandas.pydata.org/pandas-docs/version/0.17.0/generated/pandas.rolling_mean.html

4voto

ac2001 Points 359

Cette solution a fonctionné pour moi.

data['MA'] = data.rolling(5).mean()['pop']

Je pense que le problème est que le on='pop' ne fait que changer la colonne pour effectuer le roulement de la fenêtre à partir de l'index.

Extrait de la doc string : " Pour un DataFrame, colonne sur laquelle calculer la fenêtre glissante, plutôt que l'index ".

4 votes

Anit21, cela vaut la peine de revoir la réponse d'Andrew ci-dessous car elle est beaucoup plus efficace. Il est préférable de créer une série comme il l'a fait, puis de calculer la moyenne glissante sur cette seule série.

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