4 votes

Insérer une liste dans les cellules qui répondent aux conditions de la colonne

Pensez à df

   A  B  C
0  3  2  1
1  4  2  3
2  1  4  1
3  2  2  3

Je veux ajouter une autre colonne "D" de telle sorte que D contient différentes Listes basées sur des conditions sur "A" , "B" y "C"

   A  B  C  D
0  3  2  1  [1,0]
1  4  2  3  [1,0]
2  1  4  1  [0,2]
3  2  2  3  [2,0]

Mon extrait de code ressemble à ceci :

df['D'] = 0
df['D'] = df['D'].astype(object)

df.loc[(df['A'] > 1) & (df['B'] > 1), "D"] = [1,0]
df.loc[(df['A'] == 1) , "D"] = [0,2]
df.loc[(df['A'] == 2) & (df['C'] != 0) , "D"] = [2,0]

Lorsque j'essaie d'exécuter ce code, l'erreur suivante se produit :

ValueError: Must have equal len keys and value when setting with an iterable

J'ai converti la colonne en Object type comme suggéré aquí mais toujours avec une erreur.

Ce que je peux en déduire, c'est que pandas essaie d'itérer sur les éléments de la liste et attribue chacune de ces valeurs aux cellules, alors que j'essaie d'attribuer la liste entière à toutes les cellules répondant au critère.

Existe-t-il un moyen d'attribuer des listes de la manière décrite ci-dessus ?

3voto

piRSquared Points 159

Voici une façon loufoque de le faire.

cond1 = df.A.gt(1) & df.B.gt(1)
cond2 = df.A.eq(1)
cond3 = df.A.eq(2) & df.C.ne(0)

df['D'] = cond3.map({True: [2, 0]}) \
  .combine_first(cond2.map({True: [0, 2]})) \
  .combine_first(cond1.map({True: [1, 0]})) \

df

enter image description here

3voto

jezrael Points 290608

Une autre solution consiste à créer Series rempli par list con shape pour générer length de df :

df.loc[(df['A'] > 1) & (df['B'] > 1), "D"] = pd.Series([[1,0]]*df.shape[0])
df.loc[(df['A'] == 1) , "D"] = pd.Series([[0,2]]*df.shape[0])
df.loc[(df['A'] == 2) & (df['C'] != 0) , "D"] = pd.Series([[2,0]]*df.shape[0])
print (df)
   A  B  C       D
0  3  2  1  [1, 0]
1  4  2  3  [1, 0]
2  1  4  1  [0, 2]
3  2  2  3  [2, 0]

1voto

Avis de non-responsabilité : C'est ma propre question.

Les deux réponses fournies par jezrael y piRSquared travail.

Je voulais simplement ajouter une autre façon de procéder, quoique légèrement différente de celle que j'ai indiquée dans la question. Au lieu d'essayer d'insérer un list vous pouvez convertir le list en un string et y accéder plus tard par le biais du typage.

df.loc[(df['A'] > 1) & (df['B'] > 1), "D"] = '[1,0]'
df.loc[(df['A'] == 1) , "D"] = '[0,2]'
df.loc[(df['A'] == 2) & (df['C'] != 0) , "D"] = '[2,0]'

Cela ne s'applique peut-être pas à l'usage de tout le monde, mais je peux certainement penser à des situations où cela suffirait.

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