Exemple de DF:
ID Match1 Match2 Match3 Match4 Match5 Final_Match
1 Yes No Yes Yes Yes Clear
2 Yes No Yes Yes No Unclear
2 Yes No No Yes Yes Unclear
3 No Yes Yes Yes No Clear
3 No Yes No No No Unclear
4 Yes No Yes No No Unclear
4 Yes No Yes Yes Yes Clear
DF attendu:
ID Match1 Match2 Match3 Match4 Match5 1 Yes No Yes Yes Yes 2 Yes No Yes Yes No 2 Yes No No Yes Yes 3 No Yes Yes Yes No 3 No Yes No No No 4 Yes No Yes No No 4 Yes No Yes Yes Yes
Énoncé du problème:
Clear dans la colonne Final_Match (exemple d'ID 1) Si les ID sont répétitifs, dans un nombre d'ID Oui dans les colonnes Match1 à Match5, selon celui qui a le plus grand "Oui", mettez Clear pour celui-ci et Pas clair pour l'autre (ID d'exemple 3 et 4
Si les ID sont répétitifs, alors dans un nombre d'ID Oui dans les colonnes Match1 à Match5, s'ils ont égal "Oui", insérez Unclear dans les deux (Exemple ID 2)
Je n'ai rien trouvé sur la façon de résoudre dans ID?
3 Réponses :
Utilisation de pandas.DataFrame.groupby:
final_match = []
for i, d in df.groupby('ID'):
if len(d) == 1:
final_match.append('Clear')
else:
counter = (d.filter(like='Match') == 'Yes').sum(1)
if counter.nunique() == 1:
final_match.extend(['Unclear'] * len(d))
else:
final_match.extend(counter.apply(lambda x: 'Clear' if x == max(counter) else 'Unclear').tolist())
df['final_match'] = final_match
print(df)
ID Match1 Match2 Match3 Match4 Match5 final_match
0 1 Yes No Yes Yes Yes Clear
1 2 Yes No Yes Yes No Unclear
2 2 Yes No No Yes Yes Unclear
3 3 No Yes Yes Yes No Clear
4 3 No Yes No No No Unclear
5 4 Yes No Yes No No Unclear
6 4 Yes No Yes Yes Yes Clear
Explication:
len (d) == 1 : si non répétitif, ajoutez Clear counter = (d.filter (like = 'Match') == 'Yes'). sum (1) : Compte le nombre de 'Yes' dans chaque colonne counter.nunique () == 1 : si toutes les lignes ont le même nombre de "Oui", alors toutes sont marquées comme "Pas clair" counter.apply (lambda x: 'Clear' if x == max (counter) else 'Unclear'). tolist () : si les lignes ont des nombres différents de 'Yes', marquez le le plus élevé avec "Clear", reste avec "Unclear"
Le problème est que l'ID ne vient qu'une seule fois.Lorsque je lance une partie du code, le dernier_match affiche Clear mais lorsque j'exécute tout le code, il remplace Clear par Unclear
Une autre façon de procéder serait:
df['sum_yes']=df.iloc[:,1:6].eq('Yes').sum(axis=1)
df['final']=df.groupby('ID')['sum_yes'].transform\
(lambda x: np.where((x==x.max())&(~x.duplicated(keep=False)),'Clear','Unclear'))
print(df)
ID Match1 Match2 Match3 Match4 Match5 sum_yes final
0 1 Yes No Yes Yes Yes 4 Clear
1 2 Yes No Yes Yes No 3 Unclear
2 2 Yes No No Yes Yes 3 Unclear
3 3 No Yes Yes Yes No 3 Clear
4 3 No Yes No No No 1 Unclear
5 4 Yes No Yes No No 2 Unclear
6 4 Yes No Yes Yes Yes 4 Clear
PS Vous pouvez supprimer la colonne sum_yes si vous le souhaitez. p >
Si j'ai des colonnes entre ces colonnes de correspondance ou toute autre colonne à gauche ou à droite des colonnes Match d'actualités, dois-je modifier la partie iloc [:, 1: 6] ?
@RahulAgarwal oui, alors vous pouvez utiliser la méthode filter () et comme = Match comme le montre la solution de Chris. :)
Vous pouvez également y parvenir en utilisant Groupby.rank:
# Helper Series
s = (df.replace({'Yes': 1, 'No': 0})
.iloc[:, 1:]
.sum(1))
df['final_match'] = np.where(s.groupby(df['ID']).rank(ascending=False).eq(1), 'Clear', 'Unclear')
J'essaie maintenant votre solution en mettant deux colonnes dans Group by conditions, j'obtiens un "Key error" bien que j'aie ces deux colonnes par dataframe
pouvez-vous publier votre déclaration groupby ici?
np.where (s.groupby (df ['Supplier_Name_Translated', 'Spent']). r ank (ascending = False) .eq (1), 'Full Match', 'Partial Match') < / code>
Le changement est que ce n'est plus par colonne "ID" comme auparavant mais par deux autres colonnes, dont l'une est du texte et l'autre des nombres
Essayé, donne cette erreur ValueError: Grouper pour '
Vous avez cette erreur TypeError: les objets 'Series' sont mutables, ils ne peuvent donc pas être hachés
Désolé, j'ai mal tapé la dernière suggestion, pouvez-vous essayer: np.where (s.groupby ([df ['Supplier_Name_Translated'], df ['Spent']]). Rank (ascending = False) .eq (1), 'Correspondance complète', 'Correspondance partielle') ?
Ma colonne Spent était une chaîne flottante, j'ai également converti en int. mais toujours une nouvelle erreur TypeError: l'objet 'NoneType' n'est pas appelable
Y a-t-il des NaN dans Spent maintenant?
J'ai vérifié ça, il n'y a pas de 'NaN' ou de blancs d'ailleurs