web-dev-qa-db-fra.com

Pandas / Python: Définition de la valeur d'une colonne en fonction de la valeur d'une autre colonne

Je dois définir la valeur d'une colonne en fonction de la valeur d'une autre dans un Pandas dataframe. C'est la logique:

if df['c1'] == 'Value':
    df['c2'] = 10
else:
    df['c2'] = df['c3']

Je ne parviens pas à obtenir ce que je veux, c'est-à-dire créer simplement une colonne avec de nouvelles valeurs (ou modifier la valeur d'une colonne existante: l'une fonctionne pour moi).

Si j'essaie d'exécuter le code ci-dessus ou si je l'écris en tant que fonction et utilise la méthode apply, j'obtiens les éléments suivants:

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
26
NLR

une façon de le faire serait d'utiliser l'indexation avec .loc.

Exemple

En l'absence d'un exemple de cadre de données, je vais en créer un ici:

import numpy as np
import pandas as pd

df = pd.DataFrame({'c1': list('abcdefg')})
df.loc[5, 'c1'] = 'Value'

>>> df
      c1
0      a
1      b
2      c
3      d
4      e
5  Value
6      g

En supposant que vous vouliez créer une nouvelle colonnec2, équivalent à c1 sauf où c1 est Value, auquel cas vous souhaitez attribuez-le à 10:

Tout d'abord, vous pouvez créer une nouvelle colonne c2 et la définir comme équivalente à c1, en utilisant l'une des deux lignes suivantes (elles font essentiellement la même chose):

df = df.assign(c2 = df['c1'])
# OR:
df['c2'] = df['c1']

Ensuite, recherchez tous les index où c1 est égal à 'Value' à l'aide de .loc et attribuez la valeur souhaitée dans c2 à ces index:

df.loc[df['c1'] == 'Value', 'c2'] = 10

Et vous vous retrouvez avec ceci:

>>> df
      c1  c2
0      a   a
1      b   b
2      c   c
3      d   d
4      e   e
5  Value  10
6      g   g

Si, comme vous l'avez suggéré dans votre question, vous voudrez peut-être parfois simplement remplacer les valeurs de la colonne que vous avez déjà, plutôt que de créer une nouvelle colonne, ignorez simplement la création de la colonne et effectuez les opérations suivantes: Suivant:

df['c1'].loc[df['c1'] == 'Value'] = 10
# or:
df.loc[df['c1'] == 'Value', 'c1'] = 10

Te donner:

>>> df
      c1
0      a
1      b
2      c
3      d
4      e
5     10
6      g
39
sacuL

vous pouvez utiliser np.where() pour définir des valeurs basées sur une codition

#df
   c1  c2  c3
0   4   2   1
1   8   7   9
2   1   5   8
3   3   3   5
4   3   6   8

Modifiez maintenant les valeurs (ou définissez) dans la colonne ['c2'] en fonction de votre condition.

df['c2'] = np.where(df.c1 == 8,'X',df.c3)

  c1  c3 c4
0   4   1  1
1   8   9  X
2   1   8  8
3   3   5  5
4   3   8  8
8
DJK

essayer:

df['c2'] = df['c1'].apply(lambda x: 10 if x == 'Value' else x)

8
AlexanderHughes

Je suggère de le faire en deux étapes:

# set fixed value to 'c2' where the condition is met
df.loc[df['c1'] == 'Value', 'c2'] = 10

# copy value from 'c3' to 'c2' where the condition is NOT met
df.loc[df['c1'] != 'Value', 'c2'] = df[df['c1'] != 'Value', 'c3']
1
Ralf