Problème
Désolé pour tous ceux qui m'ont aidé, mais j'ai dû reformuler ma question. J'ai un dataframe avec des doublons pour la plupart des colonnes, à l'exception de la dernière colonne. Là où j'ai des doublons, je veux appliquer la règle suivante :
- Si les deux ont des entrées valides dans la dernière colonne, conserver les deux.
- Si les deux ont des entrées nulles dans la dernière colonne, conserver l'une d'entre elles.
- Si l'un a une entrée valide et l'autre une entrée nulle, conserver l'entrée valide.
Je souhaite ensuite retirer les valeurs en double et créer un cadre de données distinct. Pour l'instant, mon approche est laborieuse et supprime les deux doublons lorsqu'ils sont tous deux nuls.
Reprex
Démarrage de la base de données
import pandas as pd
import numpy as np
data_input = {'Student': ['A', 'A', 'B', 'B', 'C', 'D', 'E', 'F', 'F', 'G', "H", "H", "I", "I"],
"Subject": ["Law", "Law", "Maths", "Maths", "Maths", "Law", "Maths", "Music", "Music", "Music", "Art", "Art", "Dance", "Dance"],
"Checked": ["Bob", "James", np.nan, "Jack", "Laura", "Laura", np.nan, np.nan, "Tim", "Tim", "Tim", np.nan, np.nan, np.nan]}
# Create DataFrame
df1 = pd.DataFrame(data_input)
Résultats souhaités
Première tentative
attempt1 = df1.sort_values(['Student', 'Checked'], ascending=False).drop_duplicates(["Student", "Subject"]).sort_index()
J'ai pris cela dans une autre Q&A sur Stack, mais cela ne me donne pas le résultat que je veux et je ne le comprends pas.
Tentative 2
#Create Duplicate column
df1["Duplicates"] = df1.duplicated(subset=["Student", "Subject"], keep=False)
#Create list of rows with no duplicates
df_new1 = df1[df1["Duplicates"]==False]
#Create list of rows with duplicates & remove all those with null values
#HERE IS WHERE I GET STUCK. IF BOTH DUPLICATES ARE NULLS, I WANT TO KEEP ONE OF THEM
df_new2 = df1[df1["Duplicates"]==True]
df_new3 = df_new2[~df_new2["Checked"].isnull()]
#Combine unique rows, and duplicates without null values
#Keep duplicates without null values
df_new = df_new1.append(df_new3)
#Tidy up
df_new = df_new[["Student", "Subject", "Checked"]].sort_values(by="Student")
df_new
Je peux alors créer une liste des doublons qui apparaissent tous deux valides
#Create separate list of duplicates with valid "Checked" values
df_new["Duplicates"] = df_new.duplicated(subset="Student", keep=False)
conflicting_duplicates = df_new[df_new["Duplicates"]==True]
conflicting_duplicates
Aide
Merci à tous ! Vos réponses m'ont aidé, mais je n'avais pas réalisé que je voulais également conserver l'une des entrées où les deux sont nulles.
Existe-t-il une meilleure façon de procéder ?