Salut j'ai df comme ça:

df = pd.DataFrame({'CaseNo':[1,1,1,1,2,2,3,3,3,4,4],
                   'Category':['A','A','IOU','A','B','B','IOU','IOU','IOU','C','IOU']})

enter image description here

Je voudrais étiqueter CaseNo col en fonction de cette condition:
Pour chaque CaseNo, s'il y a une occurrence de la valeur 'IOU' dans la colonne Category avec n'importe quelle valeur (sauf 'IOU') la précédant - libellé 'OUI', sinon étiquette «NON».

Comment puis-je faire cela en Python? Résultat attendu: entrez la description de l'image ici

2
spidermarn 2 juin 2020 à 18:26

3 réponses

Essayons transform avec first et any

g=df.Category.eq('IOU').groupby(df['CaseNo'])
m=g.transform('any') & ~g.transform('first')
df['New']=m.map({True:'Yes',False:'No'})
df
Out[24]: 
    CaseNo Category  New
0        1        A  Yes
1        1        A  Yes
2        1      IOU  Yes
3        1        A  Yes
4        2        B   No
5        2        B   No
6        3      IOU   No
7        3      IOU   No
8        3      IOU   No
9        4        C  Yes
10       4      IOU  Yes
1
BEN_YO 2 juin 2020 à 15:33

Groupby avec un nombre de IOU est une façon de le résoudre:

res = (df
       .assign(val = df.groupby('CaseNo').Category.transform(",".join),
               label = lambda x: np.where(x.val.str.count("IOU").eq(1) ,"YES","NO")
              )
       .drop('val',axis=1)
      )

res


    CaseNo  Category    label
0      1       A        YES
1      1       A        YES
2      1      IOU       YES
3      1       A        YES
4      2       B        NO
5      2       B        NO
6      3     IOU        NO
7      3     IOU        NO
8      3     IOU        NO
9      4       C        YES
10     4     IOU        YES
1
sammywemmy 2 juin 2020 à 15:48

Le code suivant fait ce dont vous avez besoin. Il utilise groupby et index. L'avantage est que vous pouvez toujours modifier la fonction func pour faire une mise à jour dans ce que vous voulez. Les autres réponses sont sans aucun doute spécifiques mais ne peuvent pas être modifiées beaucoup.

def func(x):
    try:
        return 'YES' if x.index('IOU')!=0 else 'NO'
    except:
        return "NO"
mapper = df.groupby("CaseNo")['Category'].agg(list).apply(func)
df['Label'] = df['CaseNo'].apply(lambda x: mapper[x])
print(df)

Production:

    CaseNo Category Label
0        1        A   YES
1        1        A   YES
2        1      IOU   YES
3        1        A   YES
4        2        B    NO
5        2        B    NO
6        3      IOU    NO
7        3      IOU    NO
8        3      IOU    NO
9        4        C   YES
10       4      IOU   YES
1
paradoxlover 2 juin 2020 à 15:37