Existe-t-il un moyen simple de réduire le temps à zéro avec chaque nouvelle condition dans une base de données pandas ?
J'ai une trame de données de séries chronologiques à gros cul où une condition change à intervalles variables. Je voudrais mettre à zéro le temps avec chaque nouvelle condition, j'ai donc converti les catégories en nombres entiers et créé une nouvelle colonne en utilisant le.diff() pour indiquer les lignes où le commutateur se produit avec des valeurs non nulles. Ensuite, j'ai créé une nouvelle colonne, "Mod_time" comme conteneur pour les nouvelles valeurs de temps qui se mettent à zéro à chaque nouvelle condition. Voici à quoi je veux que le tableau ressemble:
Temps | État | Condition numérique | Fruit_switch | Mod_time |
---|---|---|---|---|
0 | Pommes | 6 | dans | 0 |
une | Pommes | 6 | 0 | une |
2 | Pommes | 6 | 0 | 2 |
3 | Pommes | 6 | 0 | 3 |
4 | Des oranges | 2 | -4 | 0 |
5 | Des oranges | 2 | 0 | une |
Solution du problème
Il existe toute une variété de problèmes qui impliquent une somme cumulée avec réinitialisation. Celui-ci peut être vu comme tel : vous aimeriez faire la somme cumulée des différences de temps, avec une réinitialisation lorsque la "condition numérique" change.
import numpy as np
def cumsum_reset(v, reset):
v = v.copy()
c = np.cumsum(~reset)
v[reset] = -np.diff(np.r_[0, c[reset]])
return np.cumsum(v)
# application
cond = df['Numerical Condition']
df['Mod_time'] = cumsum_reset(np.diff(np.r_[0, df['Time']]),cond!= cond.shift())
Sur vos données :
Time Condition Numerical Condition Fruit_switch Mod_time
0 0 Apples 6 NaN 0
1 1 Apples 6 0.0 1
2 2 Apples 6 0.0 2
3 3 Apples 6 0.0 3
4 4 Oranges 2 -4.0 0
5 5 Oranges 2 0.0 1
Modifier
D'après les commentaires, il semble que la réinitialisation devrait vraiment provenir du moment où df['Condition']
(le nom du fruit) change. De plus, la différence de temps entre les lignes est toujours égale à un. Par conséquent, les éléments suivants devraient également fonctionner :
c = df['Condition']
df['Mod_time'] = cumsum_reset(np.ones_like(c), c.shift()!= c)
Commentaires
Enregistrer un commentaire