Skip to content

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

O pandas 3.1.0 (22 de outubro de 2026) torna inplace=True obsoleto em drop, rename, sort_values e outros oito métodos, adiciona DataFrame.select() com expressões pd.col() e filter(cond=), e lê CSVs grandes em paralelo. Testado no macOS: um CSV de 72 MB passou de 0,23 s para 0,02 s, a lista exata de Pandas4Warning, as opções de read_csv que desligam o leitor paralelo sem avisar e a armadilha do NumPy 2.3.3 no Python 3.14.

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:

  1. Seu código imprime Pandas4Warning para cada inplace=True em drop, rename, reset_index, set_index, sort_values, dropna, drop_duplicates e alguns outros. A correção é mecânica: df = df.drop(...) em vez de df.drop(..., inplace=True). Muitas vezes o aviso vem de uma biblioteca que você usa, não do seu código.
  2. pd.read_csv em 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.
  3. Você ganha uma API no estilo Polars: df.select("a", pd.col("b") * 2) e df.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 uv limpo 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çaO 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.0Reatribua o resultado: df = df.drop(...)
read_csv paralelo para arquivos locais não comprimidos ≥ 5 MB2–3x mais rápido em uma única thread, mais até 6 threads por padrãoNada, 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 PolarsOpcional; útil em cadeias de métodos
filter(cond=...) aceita uma máscara booleanadf.filter(pd.col("a") > 1) mantém linhasCuidado: 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.1Atualize o NumPy primeiro, ou fixe pandas<3.1
Entrada numérica usa microssegundos por padrãopd.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éricasCEPs e IDs perdem os zeros à esquerdaLeia 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.

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:

PythonNumPy mínimo
3.11 – 3.132.0.2
3.14 – 3.152.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étodoinplace no 3.1Correção
drop, rename, rename_axisObsoletodf = df.drop(...)
reset_index, set_indexObsoletodf = df.reset_index()
sort_values, sort_indexObsoletodf = df.sort_values("col")
dropna, drop_duplicatesObsoletodf = df.dropna()
eval, queryObsoletodf = df.query("a > 1")
fillna, replace, where, mask, clip, interpolateMantido (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.py

Para 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.Pandas4Warning

Pandas4Warning é 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:

  1. Atualize a biblioteca. Muitas publicaram correções em poucos dias.
  2. 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)
  1. Fixe pandas<3.1 no ambiente que roda a biblioteca sem manutenção. Não fixe o pandas 3.0 para sempre; o parâmetro inplace será 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 avisaSubstituição
s.dt.dayofweek, .dayofyear, .daysinmonths.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 floatConverta para um dtype comum primeiro; isso vai lançar erro em uma versão futura
ser.values em uma coluna com fuso horárioser.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.10

Argumentos 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 depois df.select(...) falha com AttributeError: '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ça TypeError.
  • Uma coluna inexistente lança KeyError, igual a df[["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 callable

Em 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

TarefaPolarspandas 3.1
Escolher colunasdf.select("a", "b")df.select("a", "b")
Calcular uma colunadf.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 linhasdf.filter(pl.col("a") > 1)df.filter(pd.col("a") > 1)
Agregardf.select(pl.col("a").mean()) → 1 linhadf.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.

LeitorTempovs pandas 3.0.1
pandas 3.0.1, engine="c"0,233 s1x
pandas 3.1.0, mode.max_threads = 1 (serial)0,089 s2,6x
pandas 3.1.0, 2 threads0,049 s4,8x
pandas 3.1.0, 4 threads0,025 s9,3x
pandas 3.1.0, padrão (6 threads)0,018 s13x
pandas 3.1.0, engine="pyarrow"0,030 s7,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, um skiprows em 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)

ChamadaTempoParalelo?
pd.read_csv("big.csv")0,018 ssim
pd.read_csv("big.csv", usecols=["a", "c"])0,079 snão
pd.read_csv("big.csv", index_col=0)0,091 snão
pd.read_csv("big.csv", nrows=1_000_000)0,032 snão (serial, um terço do arquivo)
pd.read_csv("big.csv", converters={"b": int})0,255 snã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 snão (file handle, não um caminho)
pd.read_csv(io.StringIO(text))0,131 snão
pd.read_csv("big.csv.gz")0,163 snão (comprimido)
pd.concat(pd.read_csv("big.csv", chunksize=500_000))0,099 snão
pd.read_csv("big.csv", dtype={...})0,034 ssim (dtype explícito não atrapalha)
pd.read_csv("big.csv", na_values=["z"])0,025 ssim

Duas consequências práticas:

  • usecols agora pode deixar uma leitura mais lenta, não mais rápida. Durante anos o conselho foi "passe usecols para 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 que usecols no 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 gone

O 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çou ValueError no nosso teste; no 3.0 ele ignorava hour em 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 o PM.
  • Aritmética de DataFrame e comparações de ordem com uma Series category ao longo do axis="columns" padrão (por exemplo, df + cat_series) agora lançam TypeError em vez de operar sobre as categorias; a igualdade não mudou (docs, reproduzido).
  • Index.values e Index.array retornam 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çãoRecomendação
Projeto novo, Python 3.11+Sim. Comece no 3.1 e escreva sem inplace
Scripts e notebooks no 3.0Sim. 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 similaresAtualize 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.xFaça a migração 2 → 3 primeiro (Copy-on-Write, dtype de string); o 3.1 é pequeno em cima disso
Ainda no NumPy 1.xBloqueado. 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. Coloque warnings.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