HOWTO · Pandas
Filtrar linhas de um DataFrame pandas por valores de coluna
Filtre linhas de um DataFrame pandas com máscaras booleanas, loc, isin, between, testes de texto e nulos ou query.
Nesta página
Filtrar significa produzir um booleano por linha e manter as linhas com valor True. A forma geral df.loc[condição] é clara; o segundo argumento também escolhe as colunas de saída.
Criar o DataFrame de exemplo
A tabela contém texto, números, datas e um produto ausente. Os próximos exemplos reutilizam orders. O índice original é preservado; redefina-o apenas quando realmente precisar de outro.
import pandas as pd
orders = pd.DataFrame(
{
"order_id": [101, 102, 103, 104, 105, 106],
"region": ["East", "West", "East", "North", "West", "East"],
"product": ["Desk", "Chair", "Desk lamp", "Desk", None, "Chair"],
"sales": [450, 275, 125, 700, 320, 410],
"status": ["paid", "pending", "paid", "paid", "cancelled", "pending"],
"ordered_at": pd.to_datetime(["2026-08-01", "2026-08-03", "2026-08-08", "2026-08-11", "2026-08-14", "2026-08-18"]),
}
)
Filtrar linhas por um valor de coluna
A comparação de uma Series cria a máscara. Colchetes simples retornam as mesmas linhas, mas .loc também seleciona colunas. Use != para excluir e isna() ou notna() para valores ausentes.
east_orders = orders.loc[orders["region"] == "East"]
print(east_orders[["order_id", "region", "sales"]].to_string(index=False))
Saída:
order_id region sales
101 East 450
103 East 125
106 East 410
large_orders = orders.loc[orders["sales"] >= 400, ["order_id", "sales"]]
print(large_orders.to_string(index=False))
Saída:
order_id sales
101 450
104 700
106 410
Combinar várias condições
Combine condições elemento a elemento com &, | e ~, colocando cada comparação entre parênteses. and e or do Python esperam um único booleano e causam o erro de verdade ambígua com uma Series.
mask = (orders["region"] == "East") & (orders["sales"] >= 400)
result = orders.loc[mask, ["order_id", "region", "sales"]]
print(result.to_string(index=False))
Saída:
order_id region sales
101 East 450
106 East 410
mask = (orders["status"] == "paid") | (orders["sales"] > 600)
result = orders.loc[mask, ["order_id", "status", "sales"]]
# Raises ValueError: The truth value of a Series is ambiguous.
orders.loc[(orders["region"] == "East") and (orders["sales"] >= 400)]
Filtrar por uma lista de valores
Series.isin() substitui cadeias de comparações. Passe uma lista ou coleção semelhante, não uma string isolada. Para excluir valores, aplique ~ ao resultado completo de isin().
allowed = ["East", "West"]
result = orders.loc[orders["region"].isin(allowed), ["order_id", "region"]]
print(result.to_string(index=False))
Saída:
order_id region
101 East
102 West
103 East
105 West
106 East
excluded = ["cancelled", "pending"]
paid_only = orders.loc[~orders["status"].isin(excluded)]
Filtrar intervalos e datas
between() inclui os dois limites por padrão e também funciona com datas convertidas por pd.to_datetime(). Em dados com fuso horário, coluna e limites devem ser compatíveis.
mid_value = orders.loc[orders["sales"].between(300, 500), ["order_id", "sales"]]
print(mid_value.to_string(index=False))
Saída:
order_id sales
101 450
105 320
106 410
date_mask = orders["ordered_at"].between("2026-08-03", "2026-08-14")
result = orders.loc[date_mask, ["order_id", "ordered_at"]]
Filtrar valores ausentes ou presentes
isna() localiza None, NaN e NaT; notna() exige um valor presente. String vazia não é automaticamente ausente e deve ser normalizada ou testada separadamente.
missing_product = orders.loc[orders["product"].isna(), ["order_id", "product"]]
present_product = orders.loc[orders["product"].notna()]
print(missing_product.to_string(index=False))
Saída:
order_id product
105 None
Filtrar valores de texto
str.contains() cria uma máscara vetorizada. regex=False busca texto literal, case=False ignora maiúsculas e na=False decide que textos ausentes não correspondem.
has_desk = orders["product"].str.contains("desk", case=False, regex=False, na=False)
result = orders.loc[has_desk, ["order_id", "product"]]
print(result.to_string(index=False))
Saída:
order_id product
101 Desk
103 Desk lamp
104 Desk
Usar DataFrame.query() para expressões legíveis
Em query(), @ referencia uma variável local e nomes de coluna com espaços usam crases. Não concatene entrada não confiável: a expressão é avaliada e pode executar código.
minimum_sales = 400
result = orders.query("region == 'East' and sales >= @minimum_sales")
print(result[["order_id", "region", "sales"]].to_string(index=False))
Saída:
order_id region sales
101 East 450
106 East 410
Escolher entre .loc, colchetes e query()
Use .loc como padrão geral, colchetes para seleção simples de linhas e query() quando uma expressão controlada for mais legível. Use .copy() antes de alterar um resultado independente.
east_orders = orders.loc[orders["region"] == "East"].copy()
east_orders["sales_with_tax"] = east_orders["sales"] * 1.2
Evitar surpresas de alinhamento e tipo
Máscaras são alinhadas pelo índice; crie-as a partir do mesmo DataFrame. Converta texto numérico e datas antes da comparação e normalize texto somente quando a regra exigir.
Reutilizar e depurar máscaras booleanas
Uma máscara nomeada pode ser inspecionada, contada e testada. Nenhuma correspondência retorna um DataFrame vazio válido. DataFrame.filter() seleciona rótulos de eixo, não linhas por células.
Filtrar sem alterar os dados de origem
Para alterar a origem, atribua com .loc; para trabalhar separadamente, faça uma cópia. Essa escolha evita depender de indexação encadeada ou compartilhamento de memória.
DataFrame.loc, Series.isin, Series.between, Series.str.contains, DataFrame.query