3 votes

Comment diminuer progressivement la valeur d'une colonne d'un dataframe pandas ?

Supposons que j'ai un cadre de données comme indiqué ci-dessous :

[1] df
    name   value
     a      116
     b      116
     c      116
     d      225
     e      225
     f      225
     g      225

Maintenant, je veux que le df devienne

    name   value
     a      116
     b      115
     c      114
     d      225
     e      224
     f      223
     g      222

C'est-à-dire que lorsque le df original avait les mêmes valeurs (fixes) dans une colonne de lignes consécutives, il doit diminuer progressivement de 1. Ainsi, les valeurs dans la colonne des valeurs pour les noms a,b,c passent de 116 à 114. Et pour d,e,f,g, elles passent de 225 à 222.

Veuillez me conseiller.

5voto

jezrael Points 290608

Utilisez GroupBy.cumcount pour compter les valeurs consécutives et les soustraire de la colonne value :

#consecutive rows to Series g
g = df['value'].ne(df['value'].shift()).cumsum()
df['value'] = df['value'] - df.groupby(g).cumcount()
print (df)
  name  value
0    a    116
1    b    115
2    c    114
3    d    225
4    e    224
5    f    223
6    g    222

3voto

RafaelC Points 24675

Si les valeurs consécutives sont uniques, vous pouvez transform

df.groupby('value').value.transform(lambda k: k - k.reset_index().index)

0    116
1    115
2    114
3    225
4    224
5    223
6    222

3voto

W-B Points 94428

Utilisation de cumcount

df.value-=df.groupby('value').cumcount()
df
Out[215]: 
  name  value
0    a    116
1    b    115
2    c    114
3    d    225
4    e    224
5    f    223
6    g    222

2voto

sacul Points 29881

Il y a peut-être une façon plus propre de procéder, mais vous pouvez obtenir le résultat souhaité de cette façon :

df['value'] = (df.assign(x = df.value.diff().ne(0).cumsum())
               .groupby('x')
               .value
               .transform(lambda y: y - y.reset_index().index))
>>> df
  name  value
0    a    116
1    b    115
2    c    114
3    d    225
4    e    224
5    f    223
6    g    222

Essentiellement, cela crée une colonne qui signale des blocs consécutifs de nombres égaux (que j'ai appelés x ), regrouper par cette colonne, puis soustraire par le résultat de reset_index qui est juste un range la longueur de chaque groupe consécutif (c'est-à-dire en soustrayant 0 du premier, 1 du second, et ainsi de suite...)

0voto

Vikas Gautam Points 130

Je pense que vous devez d'abord trier la colonne de valeurs de votre cadre de données, puis vous pouvez utiliser une simple boucle for pour les valeurs décroissantes.

dataframe = dataframe.sort_values('value')                  #sort column 'value' 
j=0
for i in range(len(dataframe.index)-1):
    if(dataframe.iloc[i, 1] == dataframe.iloc[i+1,1]):            #if ith row value is equal to i+1th row value
        dataframe.iloc[i,1] = dataframe.iloc[i,1] - j             #then decrease 
        j = j + 1

    elif(dataframe.iloc[i, 1] != dataframe.iloc[i+1,1]):          # if not then decrease ith row value and again start with
        dataframe.iloc[i,1] = dataframe.iloc[i,1] - j             # j=0
        j=0

#print(j)                                                          
#print(i)
if(dataframe.iloc[i+1,1] == dataframe.iloc[i-j+1,1]):           # for last row check whether it is repeatation of original value
    dataframe.iloc[i+1,1] = dataframe.iloc[i+1,1] - j           # or not, if it is then decrease it.

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