Skip to content
Tópicos
Pandas
Pandas Filter Rows: Select Data by Condition in Python

Filtrar Linhas no Pandas: Selecionar Dados por Condição em Python

Updated on

Filtrar linhas em DataFrames pandas é uma das operações mais comuns em análise de dados. Seja limpando dados, explorando padrões ou preparando conjuntos de dados para aprendizado de máquina, você precisa selecionar linhas específicas com base em condições. O desafio é escolher o método certo entre as múltiplas abordagens de filtragem do pandas — cada uma com sintaxe, características de desempenho e casos de uso diferentes.

Muitos cientistas de dados lutam com a eficiência da filtragem, especialmente ao trabalhar com grandes conjuntos de dados ou condições complexas. Usar o método errado pode desacelerar sua análise em ordens de magnitude. Entender quando usar indexação booleana versus .query() ou .loc[] pode significar a diferença entre um script que executa em segundos versus um que leva minutos.

Este guia cobre todos os métodos de filtragem pandas com exemplos práticos, comparações de desempenho e melhores práticas. Você aprenderá indexação booleana, o método .query(), seleção .loc[], a função .where() e o método .filter(). No final, você saberá exatamente qual abordagem usar para qualquer cenário de filtragem.

📚

Entendendo os Métodos de Filtragem de Linhas do Pandas

O Pandas fornece cinco métodos principais para filtrar linhas de DataFrame, cada um adequado para diferentes cenários:

MétodoMelhor ParaExemplo de SintaxeDesempenho
Indexação BooleanaCondições simples, legibilidadedf[df['age'] > 25]Rápido para dados pequenos-médios
.query()Condições complexas, baseado em stringdf.query('age > 25 and city == "NYC"')Mais rápido para dados grandes
.loc[]Baseado em rótulos com condiçõesdf.loc[df['age'] > 25, ['name', 'age']]Seleção flexível de colunas
.where()Manter estrutura, substituir valoresdf.where(df['age'] > 25, np.nan)Preserva forma do DataFrame
.filter()Filtrar por nomes de coluna/índicedf.filter(like='total', axis=1)Padrões de nomes coluna/índice

Vamos explorar cada método com exemplos detalhados.

Indexação Booleana: A Abordagem Mais Comum

A indexação booleana filtra linhas criando uma máscara booleana (valores True/False) e aplicando-a ao DataFrame. Este é o método mais intuitivo para iniciantes.

import pandas as pd
import numpy as np
 
# Criar DataFrame de exemplo
df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
    'age': [25, 30, 35, 28, 32],
    'city': ['NYC', 'LA', 'NYC', 'Chicago', 'LA'],
    'salary': [70000, 80000, 90000, 75000, 85000]
})
 
# Filtrar linhas onde age é maior que 30
filtered = df[df['age'] > 30]
print(filtered)
#       name  age city  salary
# 2  Charlie   35  NYC   90000
# 4      Eve   32   LA   85000
 
# Ver a máscara booleana
print(df['age'] > 30)
# 0    False
# 1    False
# 2     True
# 3    False
# 4     True

A indexação booleana funciona avaliando a condição df['age'] > 30, que retorna uma Series de valores True/False. Quando você passa essa máscara para o DataFrame com df[mask], o pandas retorna apenas linhas onde a máscara é True.

Filtrando com Múltiplas Condições

Combine múltiplas condições usando operadores lógicos. Importante: Use & (e), | (ou), ~ (não) em vez das palavras-chave and, or, not do Python. Sempre envolva cada condição entre parênteses.

# Múltiplas condições com AND
filtered = df[(df['age'] > 25) & (df['city'] == 'NYC')]
print(filtered)
#       name  age city  salary
# 2  Charlie   35  NYC   90000
 
# Múltiplas condições com OR
filtered = df[(df['age'] > 30) | (df['salary'] > 80000)]
print(filtered)
#       name  age     city  salary
# 2  Charlie   35      NYC   90000
# 4      Eve   32       LA   85000
 
# Operador NOT
filtered = df[~(df['city'] == 'NYC')]
print(filtered)
#     name  age     city  salary
# 1    Bob   30       LA   80000
# 3  David   28  Chicago   75000
# 4    Eve   32       LA   85000

Usando .isin() para Múltiplos Valores

Filtre linhas onde uma coluna corresponde a qualquer valor em uma lista usando .isin():

# Filtrar linhas onde city é NYC ou LA
cities = ['NYC', 'LA']
filtered = df[df['city'].isin(cities)]
print(filtered)
#       name  age city  salary
# 0    Alice   25  NYC   70000
# 1      Bob   30   LA   80000
# 2  Charlie   35  NYC   90000
# 4      Eve   32   LA   85000
 
# Inverso: cidades NÃO na lista
filtered = df[~df['city'].isin(cities)]
print(filtered)
#     name  age     city  salary
# 3  David   28  Chicago   75000

Filtrando com .between()

O método .between() filtra valores dentro de um intervalo (inclusivo por padrão):

# Filtrar idades entre 28 e 32
filtered = df[df['age'].between(28, 32)]
print(filtered)
#     name  age     city  salary
# 1    Bob   30       LA   80000
# 3  David   28  Chicago   75000
# 4    Eve   32       LA   85000
 
# Limites exclusivos
filtered = df[df['age'].between(28, 32, inclusive='neither')]
print(filtered)
#   name  age city  salary
# 1  Bob   30   LA   80000

O Método .query(): Filtragem Baseada em String

O método .query() aceita uma expressão de string, tornando-o legível para condições complexas. É particularmente eficiente para DataFrames grandes porque usa numexpr para otimização.

# Consulta simples
filtered = df.query('age > 30')
print(filtered)
#       name  age city  salary
# 2  Charlie   35  NYC   90000
# 4      Eve   32   LA   85000
 
# Múltiplas condições
filtered = df.query('age > 25 and city == "NYC"')
print(filtered)
#       name  age city  salary
# 2  Charlie   35  NYC   90000
 
# Usando variáveis com símbolo @
min_age = 30
filtered = df.query('age > @min_age')
print(filtered)
#       name  age city  salary
# 2  Charlie   35  NYC   90000
# 4      Eve   32   LA   85000

Expressões .query() Avançadas

# Usando .isin() em query
cities = ['NYC', 'LA']
filtered = df.query('city in @cities')
print(filtered)
 
# Condições de intervalo
filtered = df.query('28 <= age <= 32')
print(filtered)
 
# Métodos de string
filtered = df.query('city.str.contains("LA")', engine='python')
print(filtered)

.loc[] para Filtragem Baseada em Rótulos

O indexador .loc[] combina filtragem de linhas com seleção de colunas. Use-o quando precisar de colunas específicas de linhas filtradas.

# Filtrar linhas e selecionar colunas
filtered = df.loc[df['age'] > 30, ['name', 'age']]
print(filtered)
#       name  age
# 2  Charlie   35
# 4      Eve   32
 
# Múltiplas condições
filtered = df.loc[(df['age'] > 25) & (df['salary'] > 75000), ['name', 'salary']]
print(filtered)
#       name  salary
# 1      Bob   80000
# 2  Charlie   90000
# 4      Eve   85000
 
# Todas as colunas
filtered = df.loc[df['city'] == 'NYC', :]
print(filtered)

Método .where(): Substituição Condicional de Valores

Ao contrário de outros métodos, .where() preserva a forma do DataFrame substituindo valores que não atendem à condição por NaN (ou um valor especificado).

# Manter valores onde age > 30, substituir outros por NaN
result = df.where(df['age'] > 30)
print(result)
#       name   age city   salary
# 0      NaN   NaN  NaN      NaN
# 1      NaN   NaN  NaN      NaN
# 2  Charlie  35.0  NYC  90000.0
# 3      NaN   NaN  NaN      NaN
# 4      Eve  32.0   LA  85000.0
 
# Substituir por valor personalizado
result = df.where(df['age'] > 30, 'FILTERED')
print(result)
 
# Remover linhas com NaN após .where()
result = df.where(df['age'] > 30).dropna()
print(result)

Método .filter(): Filtrar por Nomes de Coluna/Índice

O método .filter() filtra colunas ou linhas por seus rótulos (nomes), não por valores. Use-o para seleção de colunas baseada em padrões.

# Criar DataFrame com múltiplas colunas
df_wide = pd.DataFrame({
    'total_sales': [100, 200, 300],
    'total_profit': [20, 40, 60],
    'monthly_sales': [10, 20, 30],
    'yearly_sales': [120, 240, 360],
    'region': ['East', 'West', 'North']
})
 
# Filtrar colunas contendo 'total'
filtered = df_wide.filter(like='total')
print(filtered)
#    total_sales  total_profit
# 0          100            20
# 1          200            40
# 2          300            60
 
# Filtrar colunas usando regex
filtered = df_wide.filter(regex=r'.*sales$')
print(filtered)
#    total_sales  monthly_sales  yearly_sales
# 0          100             10           120
# 1          200             20           240
# 2          300             30           360
 
# Filtrar colunas por nomes exatos
filtered = df_wide.filter(items=['total_sales', 'region'])
print(filtered)

Filtrando Dados de String

O Pandas fornece métodos de string através do acessor .str para filtrar colunas de texto.

# Criar DataFrame com dados de texto
df_text = pd.DataFrame({
    'name': ['Alice Smith', 'Bob Johnson', 'Charlie Brown', 'David Lee'],
    'email': ['alice@gmail.com', 'bob@yahoo.com', 'charlie@gmail.com', 'david@outlook.com']
})
 
# Filtrar linhas onde name contém 'Smith'
filtered = df_text[df_text['name'].str.contains('Smith')]
print(filtered)
#          name           email
# 0  Alice Smith  alice@gmail.com
 
# Busca sem distinção de maiúsculas
filtered = df_text[df_text['name'].str.contains('smith', case=False)]
print(filtered)
 
# Filtrar por domínio de email
filtered = df_text[df_text['email'].str.endswith('gmail.com')]
print(filtered)
#            name              email
# 0   Alice Smith    alice@gmail.com
# 2  Charlie Brown  charlie@gmail.com
 
# Filtrar com regex
filtered = df_text[df_text['name'].str.match(r'^[A-C]')]
print(filtered)

Filtrando Valores Nulos e Não Nulos

Use .isna(), .notna(), .isnull() e .notnull() para filtrar com base em dados ausentes.

# Criar DataFrame com valores ausentes
df_missing = pd.DataFrame({
    'A': [1, 2, np.nan, 4],
    'B': [5, np.nan, 7, 8],
    'C': [9, 10, 11, 12]
})
 
# Filtrar linhas onde coluna A não é null
filtered = df_missing[df_missing['A'].notna()]
print(filtered)
#      A    B   C
# 0  1.0  5.0   9
# 1  2.0  NaN  10
# 3  4.0  8.0  12
 
# Filtrar linhas onde QUALQUER coluna é null
filtered = df_missing[df_missing.isna().any(axis=1)]
print(filtered)
#      A    B   C
# 1  2.0  NaN  10
# 2  NaN  7.0  11
 
# Filtrar linhas onde TODAS as colunas não são null
filtered = df_missing[df_missing.notna().all(axis=1)]
print(filtered)
#      A    B   C
# 0  1.0  5.0   9
# 3  4.0  8.0  12

Filtrando por Intervalos de Data

Ao trabalhar com colunas datetime, você pode filtrar por intervalos de data usando operadores de comparação padrão.

# Criar DataFrame com datas
df_dates = pd.DataFrame({
    'date': pd.date_range('2026-01-01', periods=10, freq='D'),
    'value': range(10)
})
 
# Filtrar datas após uma data específica
filtered = df_dates[df_dates['date'] > '2026-01-05']
print(filtered)
 
# Filtrar intervalo de datas
start_date = '2026-01-03'
end_date = '2026-01-07'
filtered = df_dates[(df_dates['date'] >= start_date) & (df_dates['date'] <= end_date)]
print(filtered)
 
# Usando .between() para datas
filtered = df_dates[df_dates['date'].between('2026-01-03', '2026-01-07')]
print(filtered)

Comparação de Desempenho: DataFrames Grandes

Diferentes métodos de filtragem têm diferentes características de desempenho. Aqui está uma comparação para um DataFrame com 1 milhão de linhas:

import time
 
# Criar DataFrame grande
np.random.seed(42)
df_large = pd.DataFrame({
    'A': np.random.randint(0, 100, 1000000),
    'B': np.random.randint(0, 100, 1000000),
    'C': np.random.choice(['X', 'Y', 'Z'], 1000000)
})
 
# Indexação booleana
start = time.time()
result = df_large[(df_large['A'] > 50) & (df_large['B'] < 30)]
print(f"Indexação booleana: {time.time() - start:.4f} segundos")
 
# Método .query()
start = time.time()
result = df_large.query('A > 50 and B < 30')
print(f"Método .query(): {time.time() - start:.4f} segundos")
 
# Método .loc[]
start = time.time()
result = df_large.loc[(df_large['A'] > 50) & (df_large['B'] < 30)]
print(f"Método .loc[]: {time.time() - start:.4f} segundos")

Insights de desempenho:

  • Indexação booleana: Rápida para condições simples, mais lenta para filtros complexos com múltiplas condições
  • .query(): Mais rápida para DataFrames grandes com múltiplas condições (usa otimização numexpr)
  • .loc[]: Similar à indexação booleana, mas mais flexível para seleção de colunas
  • .where(): Mais lenta devido à travessia completa do DataFrame, use apenas quando precisar preservar a forma

Para conjuntos de dados acima de 100.000 linhas com múltiplas condições, .query() tipicamente supera a indexação booleana em 20-40%.

Erros Comuns e Como Evitá-los

Erro 1: Usando 'and' em Vez de '&'

# ERRADO - lança ValueError
# filtered = df[df['age'] > 25 and df['city'] == 'NYC']
 
# CORRETO
filtered = df[(df['age'] > 25) & (df['city'] == 'NYC')]

Erro 2: Esquecendo Parênteses

# ERRADO - problemas de precedência de operador
# filtered = df[df['age'] > 25 & df['city'] == 'NYC']
 
# CORRETO - envolver cada condição
filtered = df[(df['age'] > 25) & (df['city'] == 'NYC')]

Erro 3: Modificando DataFrame Original

# Filtragem cria uma visão, não uma cópia
filtered = df[df['age'] > 30]
 
# ERRADO - SettingWithCopyWarning
# filtered['new_col'] = 100
 
# CORRETO - criar cópia explícita
filtered = df[df['age'] > 30].copy()
filtered['new_col'] = 100

Erro 4: Filtragem de String Sem Tratar NaN

df_with_nan = pd.DataFrame({
    'name': ['Alice', np.nan, 'Charlie']
})
 
# ERRADO - lança erro se NaN presente
# filtered = df_with_nan[df_with_nan['name'].str.contains('li')]
 
# CORRETO - tratar NaN com parâmetro na
filtered = df_with_nan[df_with_nan['name'].str.contains('li', na=False)]

Visualizar Dados Filtrados com PyGWalker

Após filtrar seu DataFrame pandas, visualizar os resultados ajuda a descobrir padrões e insights. PyGWalker (opens in a new tab) transforma DataFrames filtrados em uma interface interativa semelhante ao Tableau diretamente em notebooks Python — sem necessidade de exportar dados ou escrever código de plotagem complexo.

O PyGWalker é particularmente útil ao explorar conjuntos de dados filtrados porque permite:

  • Arrastar e soltar colunas para criar gráficos instantaneamente
  • Aplicar filtros adicionais visualmente sem escrever código
  • Alternar entre tipos de gráficos (barra, linha, dispersão, mapa de calor) em segundos
  • Exportar visualizações para relatórios ou apresentações
import pygwalker as pyg
 
# Filtrar DataFrame
filtered_df = df[(df['age'] > 25) & (df['salary'] > 75000)]
 
# Lançar visualização interativa
pyg.walk(filtered_df)

Isso abre uma interface interativa onde você pode criar visualizações arrastando colunas filtradas para o construtor de gráficos. Para analistas de dados trabalhando com múltiplas condições de filtro, o PyGWalker elimina o ciclo de iteração de filtrar → plotar → ajustar → replotar.

Perguntas Frequentes

Como filtro linhas de DataFrame pandas por condição?

Use indexação booleana com df[df['column'] > value] para condições simples. Para múltiplas condições, use & (e), | (ou), ~ (não) com parênteses: df[(df['A'] > 10) & (df['B'] < 20)]. Alternativamente, use .query() para sintaxe legível: df.query('A > 10 and B < 20').

Qual é a diferença entre .loc[] e indexação booleana?

A indexação booleana (df[df['col'] > 5]) retorna todas as colunas para linhas filtradas. .loc[] permite seleção de colunas simultaneamente: df.loc[df['col'] > 5, ['col1', 'col2']]. Ambos os métodos têm desempenho similar, mas .loc[] é mais explícito e suporta seleção de linhas baseada em rótulos.

Como filtrar DataFrame pandas com múltiplas condições?

Combine condições usando operadores & (e), | (ou), ~ (não). Sempre envolva cada condição entre parênteses: df[(df['age'] > 25) & (df['city'] == 'NYC') | (df['salary'] > 80000)]. Para condições complexas, use .query(): df.query('age > 25 and (city == "NYC" or salary > 80000)').

Quando devo usar .query() em vez de indexação booleana?

Use .query() para DataFrames grandes (>100k linhas) com múltiplas condições — é 20-40% mais rápido devido à otimização numexpr. Também é mais legível para condições complexas. Use indexação booleana para filtros simples ou quando precisar de máxima compatibilidade (.query() requer expressões de string que são mais difíceis de depurar).

Como filtro linhas onde o valor da coluna está em uma lista?

Use o método .isin(): df[df['city'].isin(['NYC', 'LA', 'Chicago'])]. Para o inverso (não na lista), use o operador ~: df[~df['city'].isin(['NYC', 'LA'])]. Isso é mais eficiente do que encadear múltiplas condições | para listas grandes.

Conclusão

Filtrar linhas de DataFrame pandas é uma habilidade fundamental para análise de dados em Python. Agora você entende cinco métodos de filtragem: indexação booleana para simplicidade, .query() para desempenho, .loc[] para seleção flexível de colunas, .where() para substituição de valores e .filter() para padrões de nomes de colunas.

Principais conclusões:

  • Use indexação booleana para filtros rápidos e legíveis em conjuntos de dados pequenos a médios
  • Escolha .query() para grandes conjuntos de dados com condições complexas (20-40% mais rápido)
  • Aplique .loc[] quando precisar tanto de filtragem de linhas quanto de seleção de colunas
  • Lembre-se de usar operadores &, |, ~ em vez de and, or, not
  • Sempre envolva condições entre parênteses para evitar problemas de precedência de operador

Domine essas técnicas de filtragem e você lidará com qualquer cenário de seleção de dados com eficiência. Para exploração interativa de dados filtrados, considere usar PyGWalker para visualizar seus resultados sem escrever código de plotagem adicional.

📚