3 votes

Fixer la valeur du cadre de données pandas sur conditionnel

Je ne trouve pas de question similaire pour cette requête. Cependant, j'ai un dataframe pandas où je veux utiliser deux des colonnes pour faire du conditionnel et si c'est vrai, remplacer les valeurs dans une de ces colonnes.

Par exemple. Une de mes colonnes est le "nom de l'article" et l'autre est la "valeur". Le "nom de l'article" peut être répété plusieurs fois. Je veux vérifier pour chaque "nom d'article", si tous les autres articles avec le même nom ont la valeur 0, puis remplacer ces "valeurs" par 100.

Je sais que cela devrait être simple, mais je n'arrive pas à m'y retrouver.

Pour que ce soit plus clair, voici

    itemname value
0      a       0
1      b       100
2      c       0
3      a       0
3      b       75
3      c       90

Je voudrais que mon instruction change ce cadre de données en

    itemname value
0      a       100
1      b       100
2      c       0
3      a       100
3      b       75
3      c       90

J'espère que cela a du sens. Je vérifie si quelqu'un d'autre a posé une question similaire et n'a pas pu trouver quelque chose dans ce cas.

3voto

jpp Points 83462

Vous pouvez utiliser GroupBy + transform pour créer un masque. Attribuez ensuite via pd.DataFrame.loc et l'indexation booléenne :

mask = df.groupby('itemname')['value'].transform(lambda x: x.eq(0).all())
df.loc[mask.astype(bool), 'value'] = 100

print(df)

  itemname  value
0        a    100
1        b    100
2        c      0
3        a    100
3        b     75
3        c     90

3voto

user3483203 Points 28606

Utilisation de transform avec any :

df.loc[~df.groupby('itemname').value.transform('any'), 'value'] = 100

Utilisation de numpy.where :

s = ~df.groupby('itemname').value.transform('any')
df.assign(value=np.where(s, 100, df.value))

Utilisation de l'addition et de la multiplication :

s = ~df.groupby('itemname').value.transform('any')
df.assign(value=df.value + (100 * s))

Les deux produisent cependant la sortie correcte, np.where et la solution finale ne modifient pas le DataFrame en place :

  itemname  value
0        a    100
1        b    100
2        c      0
3        a    100
3        b     75
3        c     90

Explication

~df.groupby('itemname').value.transform('any')

0     True
1    False
2    False
3     True
3    False
3    False
Name: value, dtype: bool

Desde 0 est une fausse valeur, nous pouvons utiliser any et de nier le résultat, pour trouver des groupes où toutes les valeurs sont égales à 0 .

3voto

Anton vBR Points 11660

Si toutes vos valeurs sont positives ou égales à 0

On pourrait utiliser la transformation avec la somme et vérifier si 0 :

m = (df.groupby('itemname').transform('sum') == 0)['value']
df.loc[m, 'value'] = 100

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