Como atualizar para o pandas 3.1: corrigir o Pandas4Warning do inplace, usar df.select() e pd.col() e ler CSVs mais rápido
Atualizado em

Resposta curta: o pandas 3.1.0 foi lançado em 22 de outubro de 2026, e a versão de correções 3.1.1 saiu em 4 de novembro. Atualize direto para o 3.1.1:
pip install --upgrade "pandas>=3.1"
# or, in a uv project
uv add "pandas>=3.1"Três coisas vão acontecer depois da atualização:
- Seu código imprime
Pandas4Warningpara cadainplace=Trueemdrop,rename,reset_index,set_index,sort_values,dropna,drop_duplicatese alguns outros. A correção é mecânica:df = df.drop(...)em vez dedf.drop(..., inplace=True). Muitas vezes o aviso vem de uma biblioteca que você usa, não do seu código. pd.read_csvem arquivos locais grandes fica muito mais rápido. No nosso teste, um arquivo de 72 MB passou de 0,23 s no pandas 3.0.1 para 0,02 s no 3.1. Alguns argumentos comuns desligam o ganho, e eles estão listados abaixo.- Você ganha uma API no estilo Polars:
df.select("a", pd.col("b") * 2)edf.filter(pd.col("a") > 1).
Se você ainda está no pandas 2.x, o salto para o 3.x (Copy-on-Write, o dtype de string padrão) é a mudança maior, e o guia de migração do pandas 3.0 (opens in a new tab) é o lugar para começar. Este guia cobre 3.0 → 3.1 e as armadilhas que encontramos.
O que foi testado: tudo o que aparece como "testado" foi executado em 1º de novembro de 2026, em um Apple M4 Max (16 núcleos, macOS), em um ambiente virtual
uvlimpo com CPython 3.14.2, pandas 3.1.0, NumPy 2.5.4 e PyArrow 26.0.0. Os números de comparação vêm do pandas 3.0.1 com NumPy 2.4.2 e sem PyArrow, na mesma máquina. O comportamento no Windows, Linux, conda e Docker vem da documentação oficial e não foi testado aqui. Em 4 de novembro de 2026, todas as afirmações testadas foram executadas de novo no pandas 3.1.1, com os mesmos resultados.
O que mudou no 3.1 e você vai notar
| Mudança | O que significa para você | O que fazer |
|---|---|---|
inplace obsoleto em 11 métodos (PDEP-8) | Cada chamada emite um Pandas4Warning; o parâmetro será removido no pandas 4.0 | Reatribua o resultado: df = df.drop(...) |
read_csv paralelo para arquivos locais não comprimidos ≥ 5 MB | 2–3x mais rápido em uma única thread, mais até 6 threads por padrão | Nada, a menos que você passe usecols, index_col, nrows ou um file handle (veja abaixo) |
DataFrame.select() (aceita expressões pd.col(), disponíveis desde o 3.0) | Escolha e calcule colunas em uma chamada, no estilo Polars | Opcional; útil em cadeias de métodos |
filter(cond=...) aceita uma máscara booleana | df.filter(pd.col("a") > 1) mantém linhas | Cuidado: uma lista posicional de booleanos ainda seleciona rótulos |
| NumPy ≥ 2.0.2 obrigatório (≥ 2.3.3 no Python 3.14) | Ambientes com NumPy 1.x não conseguem instalar o 3.1 | Atualize o NumPy primeiro, ou fixe pandas<3.1 |
| Entrada numérica usa microssegundos por padrão | pd.to_timedelta([1], unit="s") agora é timedelta64[us], não [s] | Corrige um bug de arredondamento do 3.0; use .as_unit() se precisar de uma resolução específica |
dtype="category" em read_csv infere categorias numéricas | CEPs e IDs perdem os zeros à esquerda | Leia essas colunas como str primeiro |
A lista completa está no What's new in 3.1.0 oficial (opens in a new tab). O restante deste guia percorre as tarefas em ordem: instalar, corrigir os avisos, usar a nova API, acelerar o carregamento de CSV e checar as mudanças de comportamento que podem alterar resultados sem erro.
- Como atualizar para o pandas 3.1: inplace obsoleto, df.select() e read_csv mais rápido
- Como atualizar para o OpenCode 2.0: migre config, plugins e sessões da v1
- Como atualizar para o Python 3.15: instalar com uv, usar imports preguiçosos (lazy imports) e checar seus pacotes
- Tutorial de Claude Code Mods: como criar, testar e instalar seu primeiro mod, com 15 exemplos da comunidade
- GPT Image 2.5: como usar, Flare vs Sunburst e preços da API
- Como usar o DeepSeek Harness: instalar, configurar e rodar seu primeiro agente
- Runcell Science: alternativa open source ao Claude Science para pesquisa com IA
- Como impedir o Mac de dormir: mantenha Codex, Claude Code e agentes de IA rodando
- OpenClaw vs ZeroClaw vs Pi Agent vs Nanobot: qual stack de agentes de IA você deve escolher em 2026?
- Como o Claude Code analisa notebooks Jupyter em Data Science: capacidade real, limites e alternativa melhor
- Claude Code Routines: rotinas e cron jobs para agentes de IA
- Claude Code Desktop: como ativar Bypass permissions
- Como Construir Dois Agentes Python com o Protocolo A2A do Google - Tutorial Passo a Passo
- Top 10 bibliotecas de visualização de dados em Python em 2025
Passo 1: instalar o pandas 3.1
Requisitos (testado)
O pandas 3.1.0 publica wheels para CPython 3.11 a 3.15 (requires_python >= 3.11) e está no PyPI e no conda-forge. O mínimo do NumPy depende da sua versão do Python:
| Python | NumPy mínimo |
|---|---|
| 3.11 – 3.13 | 2.0.2 |
| 3.14 – 3.15 | 2.3.3 |
A página de whatsnew só menciona 2.0.2. No Python 3.14, os metadados do wheel pedem 2.3.3, e é isso que o resolvedor aplica. Fixar o NumPy 1.x falha de imediato:
× No solution found when resolving dependencies:
╰─▶ Because pandas==3.1.1 depends on numpy>=2.3.3 and you require
pandas==3.1.1, we can conclude that you require numpy>=2.3.3.
And because you require numpy<2, we can conclude that your requirements
are unsatisfiable.Se uma dependência ainda fixa numpy<2, é essa dependência que bloqueia a atualização, não o pandas. Atualize-a ou mantenha pandas<3.1 até que ela seja atualizada.
Atualizar (testado com uv)
Instale o 3.1.1, não o 3.1.0: o 3.1.1 corrige uma regressão em que read_csv e to_csv tratavam objetos de caminho, como o tmpdir do pytest, como file handles abertos e podiam lançar erro ou gravar arquivos incompletos (What's new in 3.1.1 (opens in a new tab)).
# pip
pip install --upgrade "pandas>=3.1,<3.2"
# uv project
uv add "pandas>=3.1,<3.2"
# uv, throwaway environment to test first
uv venv p31 --python 3.14
uv pip install --python p31/bin/python "pandas==3.1.1" pyarrow
p31/bin/python -c "import pandas as pd; print(pd.__version__)"O conda-forge tem o 3.1.1 (verificado em 4 de novembro de 2026; conda install -c conda-forge "pandas>=3.1"), não testado aqui.
Instale o PyArrow também, se ainda não instalou. O pandas 3 usa o PyArrow para o dtype de string padrão quando ele está presente, e o leitor de CSV com engine="pyarrow" precisa dele.
Passo 2: corrigir o Pandas4Warning do inplace
Depois da atualização, um código como este:
df.drop(columns=["rain"], inplace=True)imprime:
Pandas4Warning: The inplace keyword in DataFrame.drop is deprecated and will be removed in a future version (PDEP-8).
See https://pandas.pydata.org/docs/dev/whatsnew/v3.1.0.html#deprecation-inplace for more details.Quais métodos são afetados (testado)
A depreciação cobre os métodos em que inplace=True nunca alterou valores no lugar. Em dropna, sort_values e nos outros métodos que reordenam linhas, sempre foi uma reatribuição, e a cópia que drop, rename ou set_index evitavam já não acontece de qualquer forma com o Copy-on-Write, que chegou no pandas 3.0.
| Método | inplace no 3.1 | Correção |
|---|---|---|
drop, rename, rename_axis | Obsoleto | df = df.drop(...) |
reset_index, set_index | Obsoleto | df = df.reset_index() |
sort_values, sort_index | Obsoleto | df = df.sort_values("col") |
dropna, drop_duplicates | Obsoleto | df = df.dropna() |
eval, query | Obsoleto | df = df.query("a > 1") |
fillna, replace, where, mask, clip, interpolate | Mantido (eles podem atualizar valores no lugar) | Nenhuma mudança necessária |
No nosso teste, todos os 11 métodos obsoletos emitiram o aviso quando chamados com inplace=True; fillna e replace não emitiram, como documentado.
A substituição é uma mudança de uma linha por chamada:
# before
df.rename(columns={"temp": "temp_c"}, inplace=True)
df.sort_values("temp_c", inplace=True)
df.reset_index(drop=True, inplace=True)
# after (same cost, chains cleanly)
df = (
df.rename(columns={"temp": "temp_c"})
.sort_values("temp_c")
.reset_index(drop=True)
)Encontre todas as chamadas no seu código (testado)
Transforme o aviso em erro por uma execução e o traceback aponta para a linha exata. O python -W não aceita uma classe de terceiros como pandas.errors.Pandas4Warning: ele imprime Invalid -W option ignored: invalid module name: 'pandas.errors' e executa o script mesmo assim. Filtre pela mensagem:
python -W "error:The inplace keyword:DeprecationWarning" your_script.pyPara transformar todo Pandas4Warning em erro, não só os de inplace:
python -c "import runpy, warnings, pandas as pd; warnings.simplefilter('error', pd.errors.Pandas4Warning); runpy.run_path('your_script.py', run_name='__main__')"Os dois comandos param com um traceback na primeira linha com inplace. O filtro por mensagem não mexe em avisos de depreciação sem relação com isso.
Para uma suíte de testes, o pytest aplica os filtros -W depois que o pandas já pode ser importado, então o nome da classe funciona ali:
pytest -W error::pandas.errors.Pandas4WarningPandas4Warning é uma subclasse de PandasDeprecationWarning, então um filtro em qualquer uma das duas funciona. Um grep também resolve boa parte:
grep -rn "inplace=True" --include="*.py" --include="*.ipynb" .Quando o aviso vem de uma biblioteca, não de você
Esse é o caso comum nas primeiras semanas depois de um lançamento. Entre 22 de outubro e 1º de novembro de 2026, o GitHub ganhou cerca de 300 issues e pull requests mencionando Pandas4Warning e cerca de 3.500 mencionando "pandas 3.1", em projetos como yfinance (29 chamadas com inplace em 8 arquivos, yfinance #3009 (opens in a new tab); corrigido no yfinance 1.8.0 em 3 de novembro), FLAML, marimo, cuDF, darts e category_encoders.
Você não consegue corrigir isso a partir do seu código. Opções, em ordem de preferência:
- Atualize a biblioteca. Muitas publicaram correções em poucos dias.
- Silencie só essa classe de aviso até a biblioteca se atualizar, em vez de silenciar todos os avisos:
import warnings
import pandas as pd
warnings.filterwarnings("ignore", category=pd.errors.Pandas4Warning)- Fixe
pandas<3.1no ambiente que roda a biblioteca sem manutenção. Não fixe o pandas 3.0 para sempre; o parâmetroinplaceserá removido no 4.0 e o aviso é o seu período de aviso prévio.
Outras depreciações que você pode encontrar no 3.1 (testado, salvo indicação)
| Código que agora avisa | Substituição |
|---|---|
s.dt.dayofweek, .dayofyear, .daysinmonth | s.dt.day_of_week, .day_of_year, .days_in_month |
df.select_dtypes(include="object") em colunas de string (já avisava no 3.0; o 3.1 acrescenta exclude="object") | Passe "str" explicitamente; "object" não significa mais "texto" no pandas 3 |
s.fillna("missing") em uma coluna float | Converta para um dtype comum primeiro; isso vai lançar erro em uma versão futura |
ser.values em uma coluna com fuso horário | ser.array, ser.to_numpy(), ou ser.dt.tz_convert(None).to_numpy() para manter o array UTC antigo |
pd.infer_freq(idx) retornando "D" | Vai retornar um objeto offset; use .freqstr ou defina future.infer_freq_returns_offset |
read_parquet(engine="fastparquet") (docs) | O fastparquet foi aposentado; use o engine PyArrow padrão |
pd.set_eng_float_format() (docs) | pd.set_option("display.precision", n) |
Passo 3: usar df.select(), pd.col() e filter(cond=)
DataFrame.select() e filter(cond=) são a nova API visível no 3.1. O pd.col() em si chegou no pandas 3.0 para assign() e .loc; no 3.1 ele passa a ser o argumento natural dos dois novos métodos. Se você já usou Polars, eles vão parecer familiares.
select escolhe e calcula colunas em uma chamada (testado)
import pandas as pd
df = pd.DataFrame({
"city": ["Tokyo", "Seoul", "Osaka"],
"temp": [18.2, 15.1, 19.5],
"rain": [12, 30, 8],
})
df.select("city", "temp") # same as df[["city", "temp"]]
df.select("city", temp_f=pd.col("temp") * 1.8 + 32) # keyword names the new column city temp_f
0 Tokyo 64.76
1 Seoul 59.18
2 Osaka 67.10Argumentos posteriores podem referenciar colunas criadas antes na mesma chamada, como em assign:
df.select(temp_c=pd.col("temp"), temp_f=pd.col("temp_c") * 1.8 + 32)pd.col("temp") é uma pandas.api.typing.Expression. Ela suporta os operadores e accessors que você usaria em uma Series, incluindo .str e .round():
df.select(pd.col("city").str.upper(), pd.col("temp").round(0))Três coisas que nos pegaram (testado):
- Não existe
.alias(). Dê nome a uma coluna calculada com a forma por palavra-chave (temp_f=...).pd.col("temp").alias("x")é construído sem reclamar, mas depoisdf.select(...)falha comAttributeError: 'Series' object has no attribute 'alias'. - Uma expressão que reduz a um escalar, como
pd.col("temp").mean(), precisa ser passada como palavra-chave (mean_temp=pd.col("temp").mean()); ela é então propagada para todas as linhas. Passada posicionalmente, lançaTypeError. - Uma coluna inexistente lança
KeyError, igual adf[["nope"]].
filter(cond=) mantém linhas por uma máscara booleana (testado)
DataFrame.filter só selecionava rótulos (items=, like=, regex=). No 3.1 ele também aceita uma máscara:
df.filter(cond=df["temp"] > 17) # a boolean Series
df.filter(pd.col("temp") > 17) # an expression, positional is fine
df.filter(lambda d: d["rain"] < 20) # a callableEm cadeia, isso se lê como Polars sem deixar de ser um DataFrame do pandas:
(
df.filter(pd.col("rain") < 20)
.select("city", "temp")
.sort_values("temp")
)Valores ausentes na máscara contam como False por padrão; passe na=True para mantê-los ou na="raise" para lançar erro.
A armadilha: uma lista simples de booleanos passada posicionalmente ainda segue o caminho de rótulos. No nosso teste, df.filter([True, False, True]) retornou um DataFrame com zero colunas e um UserWarning dizendo para usar cond=. Sempre escreva cond= quando a máscara for uma lista ou um array.
Polars vs pandas 3.1 lado a lado
| Tarefa | Polars | pandas 3.1 |
|---|---|---|
| Escolher colunas | df.select("a", "b") | df.select("a", "b") |
| Calcular uma coluna | df.select(pl.col("a") * 2) | df.select(pd.col("a") * 2) |
| Dar nome a ela | (pl.col("a") * 2).alias("a2") | df.select(a2=pd.col("a") * 2) |
| Filtrar linhas | df.filter(pl.col("a") > 1) | df.filter(pd.col("a") > 1) |
| Agregar | df.select(pl.col("a").mean()) → 1 linha | df.select(m=pd.col("a").mean()) → propagado para todas as linhas |
O pandas não está virando Polars: não há avaliação preguiçosa nem otimizador de consultas por trás do select. É uma sintaxe que deixa as cadeias legíveis e evita repetir o nome do DataFrame. Se você está pesando trocar de engine, Polars vs pandas cobre essa decisão.
Passo 4: aproveitar o read_csv mais rápido e saber o que o desliga
O benchmark (testado)
Um arquivo: 3.000.000 de linhas × 3 colunas (float, int, string), 72,5 MB, não comprimido, em SSD local. Melhor de três execuções.
| Leitor | Tempo | vs pandas 3.0.1 |
|---|---|---|
pandas 3.0.1, engine="c" | 0,233 s | 1x |
pandas 3.1.0, mode.max_threads = 1 (serial) | 0,089 s | 2,6x |
| pandas 3.1.0, 2 threads | 0,049 s | 4,8x |
| pandas 3.1.0, 4 threads | 0,025 s | 9,3x |
| pandas 3.1.0, padrão (6 threads) | 0,018 s | 13x |
pandas 3.1.0, engine="pyarrow" | 0,030 s | 7,8x |
A linha serial bate com as notas de lançamento ("duas a três vezes mais rápido"); as linhas paralelas vêm por cima disso. Seu arquivo vai ser diferente (mais colunas de string parseiam mais devagar), mas o formato do resultado é o ponto: o leitor padrão engine="c" agora é mais rápido que o PyArrow para um arquivo local simples.
As condições (docs, confirmadas pelos tempos acima)
O caminho paralelo roda automaticamente quando todas estas condições valem:
filepath_or_bufferé um caminho de arquivo local e não comprimido- o engine C padrão é usado
- as linhas de dados somam pelo menos 5 MB
mode.max_threadsé maior que 1 (padrão: número de CPUs, limitado a 6, e 1 quando o processo está restrito a uma CPU)- nenhuma opção que precise do arquivo inteiro de uma vez:
iterator,chunksize,nrows,usecols,index_col,parse_dates, umskiprowsem lista ou callable, cabeçalhos com várias linhas, ou uma codificação que não seja UTF-8
Qualquer outra coisa cai no leitor serial, e o resultado é sempre idêntico a uma leitura serial.
Como isso ficou no nosso teste (testado)
| Chamada | Tempo | Paralelo? |
|---|---|---|
pd.read_csv("big.csv") | 0,018 s | sim |
pd.read_csv("big.csv", usecols=["a", "c"]) | 0,079 s | não |
pd.read_csv("big.csv", index_col=0) | 0,091 s | não |
pd.read_csv("big.csv", nrows=1_000_000) | 0,032 s | não (serial, um terço do arquivo) |
pd.read_csv("big.csv", converters={"b": int}) | 0,255 s | não (mais lento que uma leitura simples, mas ainda mais rápido que a mesma chamada no 3.0) |
pd.read_csv(open("big.csv", "rb")) | 0,091 s | não (file handle, não um caminho) |
pd.read_csv(io.StringIO(text)) | 0,131 s | não |
pd.read_csv("big.csv.gz") | 0,163 s | não (comprimido) |
pd.concat(pd.read_csv("big.csv", chunksize=500_000)) | 0,099 s | não |
pd.read_csv("big.csv", dtype={...}) | 0,034 s | sim (dtype explícito não atrapalha) |
pd.read_csv("big.csv", na_values=["z"]) | 0,025 s | sim |
Duas consequências práticas:
usecolsagora pode deixar uma leitura mais lenta, não mais rápida. Durante anos o conselho foi "passeusecolspara pular colunas que você não precisa". Em um arquivo local ≥ 5 MB no 3.1, ler tudo em paralelo e descartar colunas depois foi 4x mais rápido queusecolsno nosso teste. Meça antes de manter o hábito antigo.- Passe um caminho, não um handle.
pd.read_csv("file.csv")é paralelo;pd.read_csv(open("file.csv"))não é. Wrappers que entregam ao pandas um objeto de arquivo aberto em vez de um caminho perdem o ganho.
Reduzir as threads dentro de uma aplicação já paralela
Se o pandas roda dentro de Dask, Ray, um pool de multiprocessing ou um worker web que já usa todos os núcleos, limite as threads para que elas não briguem:
import pandas as pd
with pd.option_context("mode.max_threads", 1):
df = pd.read_csv("large.csv")
# or globally
pd.set_option("mode.max_threads", 2)No Docker e no Kubernetes o limite segue a cota de CPU do cgroup (docs, não testado aqui), então um contêiner limitado a uma CPU lê em modo serial sem você fazer nada.
Passo 5: checar as mudanças de comportamento que não lançam erro
Estas são as mudanças com mais chance de alterar um resultado em silêncio. Cada uma foi reproduzida no 3.0.1 e no 3.1.0 (testado).
Timedelta e datetime a partir de números agora usam microssegundos por padrão
No 3.0, pd.to_timedelta([1], unit="s") produzia timedelta64[s], e a aritmética mantinha essa resolução. Dividir arredondava para segundos inteiros:
td = pd.to_timedelta([1], unit="s")
print(td / 3)
# pandas 3.0.1 → TimedeltaIndex(['0 days'], dtype='timedelta64[s]', freq=None)
# pandas 3.1.x → TimedeltaIndex(['0 days 00:00:00.333333'], dtype='timedelta64[us]', freq=None)O 3.1 corrige isso usando microssegundos por padrão, independentemente do unit com que você converte. Se o seu código comparava dtypes ou dependia da resolução [s], use .as_unit("s") explicitamente. Timestamp e to_datetime com entrada numérica mudaram do mesmo jeito.
Relacionado: Timedelta.total_seconds() agora inclui nanossegundos. pd.Timedelta(nanoseconds=1500).total_seconds() retorna 1.5e-06 em vez de 1e-06.
dtype="category" em read_csv infere categorias numéricas
from io import StringIO
data = "zip\n00501\n00501\n10001"
pd.read_csv(StringIO(data), dtype="category")["zip"].cat.categories.tolist()
# pandas 3.0.1 → ['00501', '10001']
# pandas 3.1.0 → [501, 10001] leading zeros goneO engine C agora faz o que o engine PyArrow já fazia. Para CEPs, números de conta e qualquer identificador com zeros à esquerda, leia a coluna como str e converta depois:
df = pd.read_csv("file.csv", dtype={"zip": "str"})
df["zip"] = df["zip"].astype("category")Coisas que antes passavam em silêncio e agora lançam erro
pd.Timestamp(datetime(2020, 12, 31), hour=5)lançouValueErrorno nosso teste; no 3.0 ele ignoravahourem silêncio. Passe todos os componentes por palavra-chave.pd.to_timedelta("3:25:00 PM")lança erro; o 3.0 interpretava como três horas e descartava oPM.- Aritmética de DataFrame e comparações de ordem com uma Series
categoryao longo doaxis="columns"padrão (por exemplo,df + cat_series) agora lançamTypeErrorem vez de operar sobre as categorias; a igualdade não mudou (docs, reproduzido). Index.valueseIndex.arrayretornam arrays somente leitura, então código que alterava um índice por meio deles agora falha de forma visível em vez de corromper as buscas (docs).
Regex em strings com backend PyArrow (testado)
Com o PyArrow instalado, \w, \d, \s, \b em .str.replace, .str.count e similares casavam só com ASCII no pandas 3.0. No 3.1 eles voltam a casar com Unicode, de forma consistente com o re do Python e com o pandas 2.x. Com o PyArrow 26.0.1, pd.Series(["héllo wörld", "naïve 東京"]).str.count(r"\w") retornou [8, 4] no pandas 3.0.6 e [10, 7] no 3.1.1. Se você processa texto que não é em inglês e viu as contagens caírem depois de migrar para o 3.0, esta é a correção. O 3.1.1 também corrige o \s que não casava com \x0b e \x1c em strings PyArrow.
Vale atualizar agora?
| Situação | Recomendação |
|---|---|
| Projeto novo, Python 3.11+ | Sim. Comece no 3.1 e escreva sem inplace |
| Scripts e notebooks no 3.0 | Sim. Rode uma vez com -W "error:The inplace keyword:DeprecationWarning" (ou pytest -W error::pandas.errors.Pandas4Warning), corrija as linhas e fique com as leituras de CSV mais rápidas |
Biblioteca ou pipeline que carrega IDs com zeros à esquerda usando dtype="category" | Atualize, mas adicione dtype={"id": "str"} primeiro |
| Depende de FLAML, darts ou similares | Atualize quando eles publicarem as correções para o 3.1 (o yfinance já publicou, no 1.8.0), ou filtre Pandas4Warning enquanto isso |
| Ainda no pandas 2.x | Faça a migração 2 → 3 primeiro (Copy-on-Write, dtype de string); o 3.1 é pequeno em cima disso |
| Ainda no NumPy 1.x | Bloqueado. Atualize o NumPy primeiro |
Usando o pandas 3.1 no Jupyter
Nada muda no notebook em si. Duas observações:
-W erroré uma flag de linha de comando e não se aplica a um kernel em execução. Coloquewarnings.simplefilter("error", pd.errors.Pandas4Warning)na primeira célula enquanto faz a limpeza e depois remova.- O leitor de CSV paralelo não precisa do build free-threaded do Python; ele funciona no interpretador padrão.
Quando um arquivo grande carrega em uma fração de segundo, a parte lenta passa a ser olhar para ele. O PyGWalker (opens in a new tab) 0.5.0.1 funcionou no pandas 3.1 no nosso teste (pyg.to_html(df) renderizou um frame de 50.000 linhas em 0,23 s), então uma passada de arrastar e soltar sobre o DataFrame recém-carregado é um próximo passo razoável antes de escrever o código do groupby.
Solução de problemas
ResolutionImpossible / "requires numpy>=2.3.3" — você está no Python 3.14 ou 3.15 com um pin antigo do NumPy. Atualize o NumPy ou afrouxe o pin. No Python 3.11–3.13 o mínimo é 2.0.2.
Centenas de linhas de Pandas4Warning vindas de site-packages — é uma dependência, não o seu código. Atualize-a; se ainda não houver correção, use warnings.filterwarnings("ignore", category=pd.errors.Pandas4Warning) e abra uma issue com o traceback.
read_csv não ficou mais rápido — confira a lista no Passo 4. Os culpados de sempre são usecols, index_col, um arquivo comprimido ou um objeto de arquivo em vez de um caminho. Confirme também que pd.get_option("mode.max_threads") não é 1 (por padrão é None, que significa "auto").
df.filter([...]) não retornou colunas — você passou uma lista de booleanos posicionalmente. Use df.filter(cond=[...]).
AttributeError: 'Series' object has no attribute 'alias' — expressões pd.col não têm um alias que funcione; dê nome à coluna com a forma por palavra-chave do select.
CEPs perderam os zeros à esquerda — dtype="category" agora infere inteiros. Leia como str primeiro.
O dtype do Timedelta mudou de [s] para [us] — esperado no 3.1. Use .as_unit("s") se um sistema downstream precisar de segundos.
Perguntas frequentes
O que é o Pandas4Warning e como corrigir?
É o aviso de depreciação que o pandas 3.1 emite para comportamentos que mudam no 4.0, na maioria das vezes inplace=True em drop, rename, reset_index, set_index, sort_values, dropna e drop_duplicates. Reatribua o resultado: df = df.drop(columns=["a"]). Rode python -W "error:The inplace keyword:DeprecationWarning" your_script.py (ou pytest -W error::pandas.errors.Pandas4Warning para uma suíte de testes) para parar com um traceback na primeira chamada restante; corrija e rode de novo.
O inplace=True foi removido no pandas 3.1?
Não. Ele ainda funciona no 3.1 e imprime um aviso. A remoção está prevista para o pandas 4.0, e só nos métodos que nunca modificaram dados no lugar. fillna, replace, where, mask, clip e interpolate mantêm o parâmetro.
Por que o read_csv é mais rápido, e por que o meu não é?
O engine C é 2–3x mais rápido e arquivos locais grandes são lidos em paralelo por padrão. Se você não vê diferença, provavelmente está passando usecols, index_col, nrows, chunksize, um arquivo comprimido ou um objeto de arquivo aberto. Veja a tabela no Passo 4.
O df.select() é igual ao select do Polars?
A sintaxe é parecida de propósito, mas o pandas avalia de forma imediata e não tem otimizador de consultas. Use-o para cadeias legíveis, não para desempenho.
O pandas 3.1 funciona com o Python 3.15?
Sim. Há wheels publicados para CPython 3.11 a 3.15. No 3.14 e no 3.15 você precisa do NumPy 2.3.3 ou mais novo. Para o lado Python dessa atualização, veja nosso guia de atualização para o Python 3.15.
Guias relacionados
- Pandas read_csv: o guia definitivo de pd.read_csv()
- Como remover uma coluna no Pandas
- Como filtrar linhas no Pandas
- Como renomear colunas no Pandas
- Polars vs pandas
- Guia de atualização para o Python 3.15
- Como atualizar pacotes Python