les pandas - filtre dataframe par un autre dataframe par les éléments de ligne
J'ai un dataframe df1
qui ressemble à:
c k l
0 A 1 a
1 A 2 b
2 B 2 a
3 C 2 a
4 C 2 d
et un autre appelé df2
comme:
c l
0 A b
1 C a
Je voudrais filtre df1
en ne conservant que les valeurs qui ne SONT PAS dans df2
. Les valeurs de filtre devrait être le (A,b)
et (C,a)
des n-uplets. Jusqu'à présent, j'ai essayé d'appliquer la isin
méthode:
d = df[~(df['l'].isin(dfc['l']) & df['c'].isin(dfc['c']))]
À part cela me semble trop compliqué, il retourne:
c k l
2 B 2 a
4 C 2 d
mais j'en attends:
c k l
0 A 1 a
2 B 2 a
4 C 2 d
- Comment à propos de la concaténation des valeurs des deux colonnes
c
etl
et à l'aide de cette clé?
Vous devez vous connecter pour publier un commentaire.
Vous pouvez faire cela de manière efficace en utilisant
isin
sur un multiindex construit à partir de colonnes désirées:Je pense que cela améliore sur @IanS la solution semblable, car il ne veut pas assumer tout type de colonne (c'est à dire qu'il va travailler avec des nombres ainsi que des chaînes de caractères).
(Réponse ci-dessus est un montage. La suite a été ma première réponse)
Intéressant! C'est quelque chose que je n'ai pas rencontré avant... je serais probablement le résoudre par la fusion des deux tableaux, puis la suppression de lignes où
df2
est défini. Voici un exemple, ce qui rend l'utilisation d'un tableau temporaire:Il y a peut être moyen de le faire sans l'aide du tableau temporaire, mais je ne peux pas penser à un. Aussi longtemps que vos données n'est pas énorme la méthode ci-dessus doit être rapide et de réponse suffisante.
df2 = pd.DataFrame({'c': ['A', *], 'l': [*, 'a']})
, par*
je veux dire un générique, de sorte que la valeur peut être n'importe quoi. La sortie dedf1[~i1.isin(i2)]
devrait être:pd.DataFrame({'c': ['C'], 'k': [2], 'l': ['d']})
. Est-ce possible d'atteindre par modifiying ci-dessus?C'est assez succincte et qui fonctionne bien:
Comment sur:
Je pense que c'est une approche simple lorsque vous souhaitez filtrer un dataframe basé sur plusieurs colonnes à partir d'un autre dataframe ou même fondée sur une liste personnalisée.
Une autre option qui évite de créer une colonne supplémentaire ou de faire une fusion serait de faire un groupby sur df2 pour obtenir l'distinctes (c, l) paires et ensuite il suffit de filtre df1 en les utilisant.
Pour ce petit exemple, il semble en fait de courir un peu plus vite que les pandas approche fondée sur les 666 µs vs 1.76 ms sur ma machine), mais je soupçonne qu'il pourrait être plus lent sur de plus grands exemples puisque c'est de les faire tomber dans la pure Python.