¿Cómo puedo lograr los equivalentes de SQL INy NOT IN?
Tengo una lista con los valores requeridos. Aquí está el escenario:
df = pd.DataFrame({'countries':['US','UK','Germany','China']})
countries = ['UK','China']
# pseudo-code:
df[df['countries'] not in countries]
Mi forma actual de hacer esto es la siguiente:
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'])]
Pero esto parece un horrible error. ¿Alguien puede mejorarlo?
python
pandas
dataframe
sql-function
LondonRob
fuente
fuente

Respuestas:
Puedes usar
pd.Series.isin.Para uso "IN":
something.isin(somewhere)O para "NO EN":
~something.isin(somewhere)Como ejemplo trabajado:
fuente
isinse agregó en .13.df = pd.Series({'countries':['US','UK','Germany','China']})df, tanto el mío como el suyo, es aDataFrame.countrieses una listadf[~df.countries.isin(countries)]produce aDataFrame, no aSeries, y parece funcionar incluso en 0.11.0.dev-14a04dd.countriesvariable. Bueno, el OP lo hace, y eso se hereda, pero que algo se haga mal antes no justifica hacerlo mal ahora.Solución alternativa que utiliza el método .query () :
fuente
queryya no es experimental.Pandas ofrece dos métodos:
Series.isinyDataFrame.isinpara Series y DataFrames, respectivamente.Filtrar marco de datos basado en UNA columna (también se aplica a la serie)
El escenario más común es aplicar una
isincondición en una columna específica para filtrar filas en un DataFrame.Series.isinacepta varios tipos como entradas. Las siguientes son formas válidas de obtener lo que desea:Filtrar en MUCHAS columnas
A veces, querrá aplicar una verificación de membresía 'in' con algunos términos de búsqueda en varias columnas,
Para aplicar la
isincondición a ambas columnas "A" y "B", useDataFrame.isin:A partir de esto, para retener filas donde está al menos una columna
True, podemos usar a loanylargo del primer eje:Tenga en cuenta que si desea buscar en cada columna, simplemente omita el paso de selección de columna y haga
Del mismo modo, para retener las filas donde están TODAS las columnas
True, úselasallde la misma manera que antes.Notable Menciones:
numpy.isin,query, listas por comprensión (datos de cadena)Además de los métodos descritos anteriormente, también se puede utilizar el equivalente numpy:
numpy.isin.¿Por qué vale la pena considerarlo? Las funciones NumPy suelen ser un poco más rápidas que sus equivalentes pandas debido a una menor sobrecarga. Dado que esta es una operación de elementos que no depende de la alineación del índice, hay muy pocas situaciones en las que este método no sea un reemplazo apropiado para los pandas '
isin.Las rutinas de pandas suelen ser iterativas cuando se trabaja con cadenas, porque las operaciones de cadena son difíciles de vectorizar. Hay mucha evidencia que sugiere que las comprensiones de listas serán más rápidas aquí. . Recurrimos a un
incheque ahora.Sin embargo, es mucho más difícil de especificar, así que no lo use a menos que sepa lo que está haciendo.
Por último, también hay algo
DataFrame.queryque se ha cubierto en esta respuesta . numexpr FTW!fuente
Por lo general, he estado haciendo filtros genéricos sobre filas como esta:
fuente
Quería filtrar las filas dfbc que tenían un BUSINESS_ID que también estaba en el BUSINESS_ID de dfProfilesBusIds
fuente
Recopilando posibles soluciones a partir de las respuestas:
Para IN:
df[df['A'].isin([3, 6])]Para NO EN:
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]))]fuente
logical_notes un equivalente bocado del~operador.implementar en :
implementar no como en el resto de países:
fuente