Comment puis-je atteindre les équivalents de SQL IN
etNOT IN
?
J'ai une liste avec les valeurs requises. Voici le scénario:
df = pd.DataFrame({'countries':['US','UK','Germany','China']})
countries = ['UK','China']
# pseudo-code:
df[df['countries'] not in countries]
Ma façon actuelle de procéder est la suivante:
df = pd.DataFrame({'countries':['US','UK','Germany','China']})
countries = pd.DataFrame({'countries':['UK','China'], 'matched':True})
# IN
df.merge(countries,how='inner',on='countries')
# NOT IN
not_in = df.merge(countries,how='left',on='countries')
not_in = not_in[pd.isnull(not_in['matched'])]
Mais cela semble être une horrible culpabilité. Quelqu'un peut-il l'améliorer?
python
pandas
dataframe
sql-function
LondonRob
la source
la source
Réponses:
Vous pouvez utiliser
pd.Series.isin
.Pour une utilisation "IN":
something.isin(somewhere)
Ou pour "PAS DANS":
~something.isin(somewhere)
Comme exemple travaillé:
la source
isin
été ajouté en .13.df = pd.Series({'countries':['US','UK','Germany','China']})
df
, le mien et le sien, est unDataFrame
.countries
est une liste.df[~df.countries.isin(countries)]
produit unDataFrame
, pas unSeries
, et semble fonctionner même en arrière dans 0.11.0.dev-14a04dd.countries
variable. Eh bien, le PO le fait, et c'est hérité, mais que quelque chose soit mal fait avant ne justifie pas de le faire mal maintenant.Solution alternative qui utilise la méthode .query () :
la source
query
n'est plus expérimental.Pandas propose deux méthodes:
Series.isin
etDataFrame.isin
pour Series et DataFrames, respectivement.Filtrer le DataFrame basé sur UNE colonne (s'applique également à la série)
Le scénario le plus courant consiste à appliquer une
isin
condition sur une colonne spécifique pour filtrer les lignes d'un DataFrame.Series.isin
accepte différents types d'entrée. Voici tous les moyens valables d'obtenir ce que vous voulez:Filtrer sur BEAUCOUP de colonnes
Parfois, vous souhaiterez appliquer une vérification d'adhésion "in" avec certains termes de recherche sur plusieurs colonnes,
Pour appliquer la
isin
condition aux deux colonnes "A" et "B", utilisezDataFrame.isin
:De là, pour conserver les lignes où se trouve au moins une colonne
True
, nous pouvons utiliser leany
long du premier axe:Notez que si vous souhaitez rechercher chaque colonne, vous omettez simplement l'étape de sélection de colonne et
De même, pour conserver les lignes là où se trouvent TOUTES les colonnes
True
, utilisezall
de la même manière que précédemment.Notable Mentionne:
numpy.isin
,query
, compréhensions liste (données de chaîne)En plus des méthodes décrites ci - dessus, vous pouvez également utiliser l'équivalent numpy:
numpy.isin
.Pourquoi vaut-il la peine d'envisager? Les fonctions NumPy sont généralement un peu plus rapides que leurs équivalents pandas en raison d'une surcharge réduite. Comme il s'agit d'une opération élément par élément qui ne dépend pas de l'alignement des index, il existe très peu de situations où cette méthode ne remplace pas convenablement les pandas.
isin
.Les routines Pandas sont généralement itératives lorsque vous travaillez avec des chaînes, car les opérations sur les chaînes sont difficiles à vectoriser. De nombreuses preuves suggèrent que la compréhension des listes sera plus rapide ici. . Nous avons recours à un
in
chèque maintenant.Cependant, il est beaucoup plus difficile à spécifier, alors ne l'utilisez pas à moins de savoir ce que vous faites.
Enfin, il y a aussi
DataFrame.query
ce qui a été couvert dans cette réponse . numexpr FTW!la source
Je fais généralement un filtrage générique sur des lignes comme celle-ci:
la source
Je voulais filtrer les lignes dfbc qui avaient un BUSINESS_ID qui se trouvait également dans le BUSINESS_ID de dfProfilesBusIds
la source
Collecte des solutions possibles à partir des réponses:
Pour IN:
df[df['A'].isin([3, 6])]
Pour PAS DANS:
df[-df["A"].isin([3, 6])]
df[~df["A"].isin([3, 6])]
df[df["A"].isin([3, 6]) == False]
df[np.logical_not(df["A"].isin([3, 6]))]
la source
logical_not
est un équivalent bouchée de l'~
opérateur.mettre en œuvre dans :
mettre en œuvre pas dans comme dans des pays de repos:
la source