1
votes

Python - Créez une colonne de compteur basée sur les modifications d'une autre colonne et redémarrez le compteur

J'ai un jeu de données avec les phases de la lune. Je souhaite créer une nouvelle colonne qui compte les jours de Fase One à Fase Four . Repartir de 1 une fois qu'un Fase One démarre. Donc à la fin, mon compteur aurait de 1 à 27 ou 28 jours.

J'ai vérifié ce lien mais je n'ai pas réussi à recommencer le comptage à partir de 1 Colonne de compteur dans Pandas DataFrame où elle change en fonction d'une autre colonne . J'ai essayé avec un for mais ne me donne pas le résultat que j'attendais

J'ai essayé avec un for et sans le for

  1    |    1

  1    |    1

  2    |    1

  2    |    1

  3    |    1

  4    |    1

  4    |    1

  1    |    2  

  2    |    2 ...

J'attends:

phaseM | phaseMday

  1    |    1

  1    |    2

  2    |    3

  2    |    4

  3    |    5

  4    |    6

  4    |    7

  1    |    1  

  2    |    2 ...

Ce que j'obtiens:

phaseM | phaseMday

for i in Moon.phaseIdM:
    Moon['phaseMDay'] = (Moon.phaseIdM.eq(1) 
        & Moon.phaseIdM.shift().eq(4)).cumsum() + 1

Merci d'avance pour votre aide


2 commentaires

3 Réponses :


0
votes

Cela devrait faire l'affaire, mais je suis presque sûr qu'il existe un moyen vectorisé de faire de même.

df=pd.DataFrame([1,1,2,2,3,3,4,4,1,2],columns=['phaseM'])
df['phaseMday']=np.linspace(1,len(df),len(df))
for i in range(1,len(df1)):
    if df['phaseM'].iloc[i]<df['phaseM'].iloc[i-1]:
        df['phaseMday'].iloc[i]=1
    else:
        df['phaseMday'].iloc[i]=df1['phaseMday'].iloc[i-1]+1


0 commentaires

1
votes

Vous pouvez le faire en affectant d'abord des valeurs incrémentielles à la colonne all, puis en supprimant la valeur de la dernière ligne de départ Face One à toutes les lignes sous en vérifiant où la condition d'un nouveau début est et utilise cummax tel que:

print (Moon)
   phaseIdM  phaseMDay
0         1          1
1         1          2
2         2          3
3         2          4
4         3          5
5         4          6
6         4          7
7         1          1
8         2          2

Et vous obtenez:

Moon['phaseMDay'] = np.arange(len(Moon))
Moon['phaseMDay'] -= (Moon['phaseMDay']*(Moon.phaseIdM.eq(1) 
                                         & Moon.phaseIdM.shift().eq(4)).values).cummax()-1 


3 commentaires

Merci @Ben. T. À un moment donné, ce code fonctionne mais il commence à compter les nombres négatifs et grands. (J'ai 2559 lignes) et au milieu, il commence à compter la phaseMDay -107284, 107285 ...


@Monitotier oui désolé, remplacez cumsum par cummax ça devrait être mieux


ouais, ça a tout changé;) Merci, ça a parfaitement fonctionné



2
votes

Vous pouvez créer un groupeur Phase 1-Phase 4 comme suit:

df['phaseMday'] = df.groupby('phase_group').cumcount()+1

Regroupez ensuite et effectuez un comptage cumulatif:

df['phase_group'] = ((df['phaseM']==1) & (df['phaseM'].shift()==4)).cumsum()

p >


0 commentaires