J'ai deux trames de données pandas qui ont des lignes en commun.
Supposons que dataframe2 soit un sous-ensemble de dataframe1.
Comment puis-je obtenir les lignes de dataframe1 qui ne sont pas dans dataframe2?
df1 = pandas.DataFrame(data = {'col1' : [1, 2, 3, 4, 5], 'col2' : [10, 11, 12, 13, 14]})
df2 = pandas.DataFrame(data = {'col1' : [1, 2, 3], 'col2' : [10, 11, 12]})
Réponses:
Une méthode consisterait à stocker le résultat d'une fusion interne à partir des deux dfs, puis nous pouvons simplement sélectionner les lignes lorsque les valeurs d'une colonne ne sont pas dans cette commune:
ÉDITER
Une autre méthode que vous avez trouvée consiste à utiliser
isin
ce qui produira desNaN
lignes que vous pouvez supprimer:Cependant, si df2 ne démarre pas les lignes de la même manière, cela ne fonctionnera pas:
produira le df entier:
la source
df1[~df1.isin(df2)].dropna(how = 'all')
semble faire l'affaire. Merci quand même - votre réponse m'a aidé à trouver une solution.isin
nécessite que les deux dfs commencent avec les mêmes valeurs de ligne, par exemple si df2 étaitdf2 = pd.DataFrame(data = {'col1' : [2, 3,4], 'col2' : [11,12, 13]})
alors votre méthode ne fonctionnera paskeep=False
:df0.append(df1).drop_duplicates(keep=False)
par défaut , il conserve le premier doublon, vous voulez supprimer tous les doublonsLa solution actuellement sélectionnée produit des résultats incorrects. Pour résoudre correctement ce problème, nous pouvons effectuer une jointure gauche de
df1
àdf2
, en nous assurant d'obtenir d'abord uniquement les lignes uniques pourdf2
.Tout d'abord, nous devons modifier le DataFrame d'origine pour ajouter la ligne avec les données [3, 10].
Effectuez une jointure gauche, en éliminant les doublons
df2
afin que chaque ligne dedf1
jointures avec exactement 1 ligne dedf2
. Utilisez le paramètreindicator
pour renvoyer une colonne supplémentaire indiquant de quelle table provient la ligne.Créez une condition booléenne:
Pourquoi les autres solutions sont mauvaises
Quelques solutions font la même erreur - elles vérifient seulement que chaque valeur est indépendamment dans chaque colonne, pas ensemble dans la même ligne. L'ajout de la dernière ligne, qui est unique mais contient les valeurs des deux colonnes de,
df2
expose l'erreur:Cette solution obtient le même mauvais résultat:
la source
df_all[df_all['_merge'] == 'left_only']
pour avoir un df avec les résultatsEn supposant que les index sont cohérents dans les trames de données (sans tenir compte des valeurs de col réelles):
la source
df1
desquelles les index ne sont PASdf2.index
". Plus d'informations sur la négation: stackoverflow.com/q/19960077/304209 (étonnamment, je n'ai trouvé aucune mention de tilde dans les documents pandas).ValueError: Item wrong length x instead of y.
Comme déjà indiqué, isin requiert que les colonnes et les indices soient identiques pour une correspondance. Si la correspondance ne doit concerner que le contenu des lignes, une façon d'obtenir le masque pour filtrer les lignes présentes consiste à convertir les lignes en un (multi) index:
Si l'index doit être pris en compte, set_index a un argument de mot-clé ajouté pour ajouter des colonnes à l'index existant. Si les colonnes ne s'alignent pas, la liste (df.columns) peut être remplacée par des spécifications de colonne pour aligner les données.
pourrait également être utilisé pour créer les indices, bien que je doute que ce soit plus efficace.
la source
Supposons que vous ayez deux cadres de données, df_1 et df_2 ayant plusieurs champs (noms_colonnes) et que vous souhaitez rechercher les seules entrées dans df_1 qui ne sont pas dans df_2 sur la base de certains champs (par exemple, champs_x, champs_y), suivez les étapes suivantes.
Étape 1: ajoutez une colonne key1 et key2 à df_1 et df_2 respectivement.
Étape 2: fusionnez les cadres de données comme indiqué ci-dessous. field_x et field_y sont nos colonnes souhaitées.
Étape 3. Sélectionnez uniquement les lignes de df_1 où clé1 n'est pas égale à clé2.
Step4.Drop key1 et key2.
Cette méthode résoudra votre problème et fonctionne rapidement même avec des ensembles de données volumineux. Je l'ai essayé pour les trames de données avec plus de 1 000 000 de lignes.
la source
un peu en retard, mais cela vaut peut-être la peine de vérifier le paramètre "indicateur" de pd.merge.
Voir cette autre question pour un exemple: comparer les DataFrames PandaS et renvoyer les lignes manquantes dans la première
la source
vous pouvez le faire en utilisant la méthode isin (dict) :
Explication:
la source
Vous pouvez également concaténer
df1
,df2
:puis supprimez tous les doublons:
la source
Que dis-tu de ça:
la source
Voici une autre façon de résoudre ce problème:
Ou:
la source
Ma façon de procéder consiste à ajouter une nouvelle colonne unique à une trame de données et à l'utiliser pour choisir de conserver une entrée
Cela fait en sorte que chaque entrée dans df1 a un code - 0 s'il est unique à df1, 1 s'il se trouve dans les deux dataFrames. Vous l'utilisez ensuite pour vous limiter à ce que vous voulez
la source
la source