les pandas de roulement calcul avec fenêtre basée sur les valeurs au lieu de compte
Je suis à la recherche d'un moyen de faire quelque chose comme les différents rolling_*
fonctions de pandas
, mais je veux que la fenêtre des rolling calcul défini par un intervalle de valeurs (par exemple, une plage de valeurs d'une colonne d'un DataFrame), pas par le nombre de lignes dans la fenêtre.
Comme un exemple, supposons que j'ai ces données:
>>> print d
RollBasis ToRoll
0 1 1
1 1 4
2 1 -5
3 2 2
4 3 -4
5 5 -2
6 8 0
7 10 -13
8 12 -2
9 13 -5
Si je fais quelque chose comme rolling_sum(d, 5)
, je reçois un roulement somme dont chaque fenêtre contient 5 lignes. Mais ce que je veux, c'est un roulement somme dont chaque fenêtre contient une certaine gamme de valeurs de RollBasis
. C'est que j'aimerais être en mesure de faire quelque chose comme d.roll_by(sum, 'RollBasis', 5)
, et d'obtenir un résultat où la première fenêtre contient toutes les lignes dont le RollBasis
est entre 1 et 5, puis la deuxième fenêtre contient toutes les lignes dont le RollBasis
est entre 2 et 6, puis la troisième fenêtre contient toutes les lignes dont le RollBasis
est entre 3 et 7, etc. Windows n'auront pas le même nombre de lignes, mais la gamme de RollBasis
valeurs sélectionnées dans chaque fenêtre sera le même. La sortie devrait ressembler à:
>>> d.roll_by(sum, 'RollBasis', 5)
1 -4 # sum of elements with 1 <= Rollbasis <= 5
2 -4 # sum of elements with 2 <= Rollbasis <= 6
3 -6 # sum of elements with 3 <= Rollbasis <= 7
4 -2 # sum of elements with 4 <= Rollbasis <= 8
# etc.
Je ne peux pas faire cela avec groupby
, parce que groupby
produit toujours disjoints groupes. Je ne peux pas le faire avec les rolling fonctions, parce que leur windows toujours rouler en nombre de lignes, pas par des valeurs. Alors, comment puis-je le faire?
OriginalL'auteur BrenBarn | 2013-01-13
Vous devez vous connecter pour publier un commentaire.
Je pense que cela ne ce que vous voulez:
La fonction ci-dessus prend une valeur, dans ce cas RollBasis, puis les indices de la trame de données de la colonne ToRoll en fonction de cette valeur. Le retour de la série se compose de ToRoll valeurs qui répondent à la RollBasis + 5 critère. Enfin, cette série est résumée et retourné.
Code pour le jouet exemple DataFrame dans le cas où quelqu'un d'autre veut essayer:
OriginalL'auteur Zelazny7
Basé sur Zelazny7 réponse, j'ai créé ce plus de solution générale:
Il n'est toujours pas idéal, car il est très lent par rapport à
rolling_apply
, mais c'est peut-être inévitable.OriginalL'auteur BrenBarn
Basé sur BrenBarns réponse, mais accéléré par l'utilisation de l'étiquette en fonction de l'indexation plutôt que booléen basé sur l'indexation:
C'est beaucoup plus vite que vous n'utilisez pas une colonne indexée:
Il est intéressant de noter que l'indice en fonction de la solution est O(n), tandis que la logique de découpage version est O(n^2) dans le cas moyen (je pense).
Je trouve qu'il est plus utile de le faire via les fenêtres régulièrement espacées à partir de la valeur min de la Base de la valeur max de Base, plutôt qu'à chaque valeur de base. Cela signifie modifiant la fonction ainsi:
Ce ne sont pas les mêmes résultats que Bren de réponse en raison de la façon dont ils traitent ouvert/fermé intervalles (voir résultat de l'indice 5 dans l'exemple). Il ne permet pas non plus de quoi être un DF au lieu de juste une série.
OriginalL'auteur Ian Sudbery