Como posso obter os equivalentes de SQL IN
eNOT IN
?
Eu tenho uma lista com os valores necessários. Aqui está o cenário:
df = pd.DataFrame({'countries':['US','UK','Germany','China']})
countries = ['UK','China']
# pseudo-code:
df[df['countries'] not in countries]
Minha maneira atual de fazer isso é a seguinte:
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'])]
Mas isso parece um sentimento horrível. Alguém pode melhorar isso?
python
pandas
dataframe
sql-function
LondonRob
fonte
fonte
Respostas:
Você pode usar
pd.Series.isin
.Para "IN", use:
something.isin(somewhere)
Ou para "NOT IN":
~something.isin(somewhere)
Como um exemplo trabalhado:
fonte
isin
foi adicionado em 0,13.df = pd.Series({'countries':['US','UK','Germany','China']})
df
, tanto o meu quanto o dele, é umDataFrame
.countries
é uma lista.df[~df.countries.isin(countries)]
produz aDataFrame
, não aSeries
e parece funcionar mesmo em 0.11.0.dev-14a04dd.countries
variável. Bem, o OP faz isso, e isso é herdado, mas que algo é feito mal antes, não justifica fazê-lo agora.Solução alternativa que usa o método .query () :
fonte
query
não é mais experimental.O Pandas oferece dois métodos:
Series.isin
eDataFrame.isin
para Series e DataFrames, respectivamente.Filtrar DataFrame com base em uma coluna (também se aplica a séries)
O cenário mais comum é aplicar uma
isin
condição em uma coluna específica para filtrar linhas em um DataFrame.Series.isin
aceita vários tipos como entradas. A seguir, são apresentadas todas as formas válidas de obter o que você deseja:Filtrar em MUITAS colunas
Às vezes, convém aplicar uma verificação de associação "com" com alguns termos de pesquisa em várias colunas,
Para aplicar a
isin
condição às duas colunas "A" e "B", useDataFrame.isin
:A partir disso, para manter as linhas onde há pelo menos uma coluna
True
, podemos usarany
ao longo do primeiro eixo:Observe que, se você deseja pesquisar todas as colunas, omite a etapa de seleção de colunas e faça
Da mesma forma, para manter as linhas onde estão TODAS as colunas
True
, useall
da mesma maneira que antes.Notável Menções:
numpy.isin
,query
, compreensões lista (dados de cadeia)Além dos métodos descritos acima, você também pode usar o equivalente numpy:
numpy.isin
.Por que vale a pena considerar? As funções do NumPy geralmente são um pouco mais rápidas que seus equivalentes de pandas, devido à menor sobrecarga. Como essa é uma operação elementar que não depende do alinhamento do índice, há muito poucas situações em que esse método não é um substituto apropriado para os pandas.
isin
.As rotinas do Pandas geralmente são iterativas ao trabalhar com strings, porque é difícil vetorizar operações de strings. Há muitas evidências para sugerir que a compreensão da lista será mais rápida aqui. . Recorremos a um
in
cheque agora.No entanto, é muito mais difícil especificar, portanto, não o use, a menos que você saiba o que está fazendo.
Por fim, há também o
DataFrame.query
que foi abordado nesta resposta . numexpr FTW!fonte
Eu costumo fazer filtragem genérica em linhas como esta:
fonte
Eu queria filtrar as linhas dfbc que tinham um BUSINESS_ID que também estava no BUSINESS_ID de dfProfilesBusIds
fonte
Reunindo possíveis soluções a partir das respostas:
Para IN:
df[df['A'].isin([3, 6])]
Para NOT IN:
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]))]
fonte
logical_not
é um equivalente da boca do~
operador.implementar em :
implementar não nos países de descanso:
fonte