Skip to main content

geocodebr Python: Geolocalização de Endereços Brasileiros

PyPI python-check python-parity Codecov test coverage

Versão Python do geocodebr, usando DuckDB como motor tabular principal. A proposta é preservar a dinâmica de uso do pacote R, incluindo nomes de funções em português, mantendo o processamento interno em SQL/DuckDB para boa performance e menor uso de memória.

O pacote geolocaliza endereços brasileiros sem limite de número de consultas, com base em dados abertos do CNEFE (Cadastro Nacional de Endereços para Fins Estatísticos), publicado pelo IBGE.

Instalação

No momento, esta versão Python ainda está em desenvolvimento dentro deste repositório (a publicação no PyPI está planejada). Para instalar localmente:

cd python-package
python -m pip install -e .

Dependências principais:

  • duckdb: motor principal de dados e SQL.
  • pyarrow: formato padrão de retorno e interoperabilidade com Parquet.
  • enderecobr: padronização dos endereços, garantindo paridade com o pacote R.
  • polars: processamento tabular interno, usado para integrar o enderecobr.
  • requests: download dos dados do CNEFE.
  • h3: criação opcional de células H3.

Utilização

O pacote possui três funções principais:

  1. geocode()
  2. geocode_reverso()
  3. busca_por_cep()

As funções retornam, por padrão, um pyarrow.Table. Caso precise converter para pandas, use .to_pandas() no resultado final. Passando resultado_gpd=True, o retorno é um geopandas.GeoDataFrame de pontos no CRS SIRGAS 2000 (EPSG 4674), equivalente ao sf do pacote R. Esse retorno exige o extra geo na instalação (python -m pip install geocodebr[geo]).

1. Geolocalização: de endereços para coordenadas

Primeiro, indique quais colunas da sua tabela representam cada campo do endereço usando definir_campos(). Depois, chame geocode().

Por padrão, os endereços são padronizados internamente pela função enderecobr_padronizar_enderecos(), o que é essencial para uma geolocalização correta. O primeiro uso pode baixar os dados do CNEFE para o cache local.

import polars as pl

from geocodebr import definir_campos, geocode

enderecos = pl.DataFrame({
    "logradouro": ["RUA PRESIDENTE VARGAS", "AVENIDA PAULISTA"],
    "numero": [123, 1000],
    "cep": ["20080-901", "01310-100"],
    "localidade": ["Centro", "Bela Vista"],
    "municipio": ["RIO DE JANEIRO", "SAO PAULO"],
    "estado": ["RJ", "SP"],
})

campos = definir_campos(
    logradouro="logradouro",
    numero="numero",
    cep="cep",
    localidade="localidade",
    municipio="municipio",
    estado="estado",
)

resultado = geocode(
    enderecos=enderecos,
    campos_endereco=campos,
    resultado_completo=False,
    resolver_empates=True,
    h3_res=[8, 10],
    verboso=False,
)

print(resultado.schema.names)
print(resultado.to_pandas().head())

Também é possível passar diretamente um caminho para arquivo .csv ou .parquet:

resultado = geocode(
    enderecos="caminho/para/enderecos.csv",
    campos_endereco=campos,
    verboso=False,
)

O resultado preserva as colunas originais e adiciona, entre outras:

  • lat
  • lon
  • precisao
  • tipo_resultado
  • desvio_metros
  • endereco_encontrado

Com resultado_completo=True, também retorna campos encontrados no CNEFE, como logradouro_encontrado, numero_encontrado, cep_encontrado, localidade_encontrada, municipio_encontrado, estado_encontrado, similaridade_logradouro, contagem_cnefe, empate e cod_setor.

2. Geolocalização reversa: de coordenadas para endereços

geocode_reverso() busca o endereço mais próximo de cada ponto dentro de uma distância máxima em metros. Assim como no R, a entrada deve ser um GeoDataFrame de pontos no CRS SIRGAS 2000 (EPSG:4674), e o retorno é o próprio GeoDataFrame de input acrescido dos campos do endereço encontrado e da coluna distancia_metros. Esta função requer o extra geo (pip install geocodebr[geo]).

import geopandas as gpd

from geocodebr import geocode_reverso

pontos = gpd.GeoDataFrame(
    {"id": [1, 2]},
    geometry=gpd.points_from_xy([-47.9001, -43.2001], [-15.8001, -22.9001]),
    crs="EPSG:4674",
)

enderecos_proximos = geocode_reverso(
    pontos=pontos,
    dist_max=1000,
    verboso=False,
)

print(enderecos_proximos)

O resultado inclui os campos do endereço encontrado e a coluna distancia_metros.

3. Busca por CEP

busca_por_cep() retorna os endereços associados a um ou mais CEPs.

from geocodebr import busca_por_cep

ceps = ["70390-025", "20071-001", "99999-999"]

resultado_cep = busca_por_cep(
    cep=ceps,
    h3_res=10,
    verboso=False,
)

print(resultado_cep.to_pandas())

O resultado inclui:

  • cep
  • estado
  • municipio
  • logradouro
  • localidade
  • lon
  • lat

Se h3_res for informado, o pacote adiciona colunas como h3_08 ou h3_10.

Padronização de endereços

A função enderecobr_padronizar_enderecos() também está disponível publicamente, para padronizar os endereços antes da geolocalização (ou usá-la de forma independente). Ela recebe um polars.DataFrame e o dicionário criado com definir_campos(), e adiciona as colunas *_padr:

from geocodebr import enderecobr_padronizar_enderecos

enderecos_padrao = enderecobr_padronizar_enderecos(
    enderecos=enderecos,
    campos_do_endereco=campos,
    formato_estados="sigla",
    formato_numeros="integer",
    manter_cols_extras=True,
)

Se os seus dados já estiverem padronizados (ou seja, já contiverem as colunas *_padr), chame geocode(..., padronizar_enderecos=False) para pular essa etapa.

Precisão dos resultados

Os resultados do geocode() são classificados em seis categorias de precisao ("numero", "numero_aproximado", "logradouro", "cep", "localidade" e "municipio"), desagregadas em códigos de tipo_resultado (e.g. dn01, pa03), e incluem a coluna desvio_metros, com uma estimativa da incerteza da localização encontrada. A interpretação dessas colunas, o significado de cada código e as regras de resolução de empates estão documentadas na vignette "geocode".

Cache dos dados do CNEFE

Na primeira execução, o pacote baixa arquivos Parquet do release do CNEFE usado pelo geocodebr. Esses arquivos ficam em cache local para acelerar chamadas futuras.

from geocodebr import (
    definir_pasta_cache,
    listar_pasta_cache,
    listar_dados_cache,
    deletar_pasta_cache,
    download_cnefe,
)

print(listar_pasta_cache())

download_cnefe(tabela="municipio_logradouro_cep_localidade", verboso=True)

arquivos = listar_dados_cache()
print(arquivos)

# definir uma pasta de cache específica
definir_pasta_cache("D:/dados/geocodebr-cache", verboso=True)

# apagar cache configurado
# deletar_pasta_cache()

Processamento interno (DuckDB-first)

Esta versão evita usar pandas no pipeline interno. O fluxo principal registra as entradas no DuckDB, executa joins/filtros/matches em SQL e só materializa o resultado no final como pyarrow.Table.

A padronização dos endereços é a única etapa fora do DuckDB: é feita em polars, fazendo a ponte com os bindings Python do enderecobr, sem materializar pandas em nenhum momento.

Isso facilita a paridade com o pacote R, que também usa DuckDB para o motor de geocodificação, e ajuda em bases maiores.

Windows e performance

No Windows, o python.exe roda por padrão no heap NT legacy e não no mais moderno e eficaz Segment Heap. O heap legado degrada sob alocação multithread intensa do DuckDB: o geocode() fica mais lento e piora a cada chamada na mesma sessão (contexto em duckdb/duckdb#24027 e no relatório de diagnóstico do pacote).

O pacote mitiga o problema de duas formas:

  1. Limitação automática de threads — no Windows sem Segment Heap, se n_cores não for definido, o geocode() limita o DuckDB a min(4, núcleos da máquina) threads (mínimo da curva tempo x threads no heap legacy, confirmado por sweep com o workload canônico do duckdb#24027 — benchmarks/verifica_sweep_threads.py; bacia plana entre 3 e 6 threads) e emite um aviso uma vez por sessão. Um n_cores passado de forma explícita é respeitado.

  2. Interpretador com Segment Heap (recomendado) — usuário pode gerar uma cópia do interpretador Python com o manifesto patcheado com o Segment Heap e rodar o geocode() a partir dele. Para criar a cópia, basta rodar:

    python -m geocodebr._heap_patch
    

    O comando cria o arquivo python-geocodebr-sh.exe ao lado do interpretador base (python.exe), sem alterar o original. Inicie a sessão pela cópia para que o DuckDB use o Segment Heap.

    Em benchmarks internos com 10 milhões de endereços, o tempo total do geocode() caiu de 11:47 minutos para 3:08 minutos.

Limitações conhecidas das soluções apresentadas para uso do geocodebr no Windows:

  • Interpretador com Segment Heap requer Windows 10 (build 19041) ou superior.

  • Não existe configuração do Windows (variável de ambiente ou registro) que ligue o Segment Heap por processo. A camada de compatibilidade — via __COMPAT_LAYER=SEGMENTHEAP ou persistida no registro (AppCompatFlags\Layers / Image File Execution Options) — não alcança o heap criado no startup, por onde passam as alocações do DuckDB.

  • O ganho vale apenas para sessões iniciadas pela cópia (python-geocodebr-sh.exe); Jupyter/IDEs que lançam outro interpretador não se beneficiam.

  • A cópia é criada na pasta do interpretador base; se ela não for gravável (ex.: Program Files), execute o terminal como administrador ou use uma instalação por usuário (ex.: uv, pyenv).

  • A cópia usa os pacotes do ambiente base. Com geocodebr instalado em venv, aponte PYTHONPATH para o site-packages da venv. Exemplo em PowerShell:

     $env:PYTHONPATH = "C:\caminho\para\.venv\Lib\site-packages"; & "C:\caminho\para\python-geocodebr-sh.exe" "C:\caminho\para\seu_script.py"
    
  • A limitação de threads reduz a contenção do heap, mas não elimina a deterioração entre chamadas sucessivas na mesma sessão; a cópia com Segment Heap resolve os dois problemas.

Desenvolvimento e testes

Para rodar a suíte de testes:

uv run pytest -q -m "not r_parity"

Esse comando roda apenas os testes unitários, com Parquets sintéticos, sem baixar dados do CNEFE.

Testes de paridade R vs Python

O pacote também inclui testes que comparam a saída do Python com a saída do pacote R usando os dados de exemplo inst/extdata/small_sample.csv e inst/extdata/large_sample.parquet.

Esses testes exigem Rscript no PATH, instalam o pacote R localmente em uma biblioteca temporária e podem baixar dados do CNEFE. Se Rscript não estiver disponível, eles são pulados automaticamente.

uv run pytest -m r_parity -q

Exemplos

A pasta exemplos/ contém scripts simples usando as funções principais da versão Python:

  • geocode_enderecos.py: busca coordenadas a partir de endereços.
  • busca_por_cep.py: busca endereços/coordenadas a partir de CEPs.
  • geocode_reverso.py: busca endereço próximo a coordenadas.

Execute os exemplos a partir da raiz do repositório:

uv run python exemplos/geocode_enderecos.py
uv run python exemplos/busca_por_cep.py
uv run python exemplos/geocode_reverso.py

Nota IPEA

Os dados originais do CNEFE são coletados pelo Instituto Brasileiro de Geografia e Estatística (IBGE). O {geocodebr} foi desenvolvido por uma equipe do Instituto de Pesquisa Econômica Aplicada (Ipea), e conta com apoio do Instituto Todos pela Saúde (ITpS).

Instituições utilizando o {geocodebr}

Além de diversos pesquisadores e empresas que utilizam o {geocodebr}, o pacote também tem sido utilizado por algumas instituições públicas no planejamento e avaliação de políticas públicas. Entre elas:

  • Instituto Brasileiro de Geografia e Estatistica (IBGE)
  • Banco Central do Brasil (BCB)
  • Ministério do Desenvolvimento Social e Combate à Fome (MDS)

Projetos relacionados

Existem diversos pacotes de geolocalização disponíveis, muitos dos quais podem ser utilizados em Python (listados abaixo). A maioria dessas alternativas depende de softwares e conjuntos de dados comerciais, geralmente impondo limites de número de consultas gratuitas. Em contraste, as principais vantagens do geocodebr são que o pacote: (a) é completamente gratuito, permitindo consultas ilimitadas sem nenhum custo; (b) opera com alta velocidade e escalabilidade eficiente, permitindo geocodificar milhões de endereços em apenas alguns minutos, sem a necessidade de infraestrutura computacional avançada ou de alto desempenho.

  • geopy: cliente para diversos serviços de geocodificação (Nominatim/OSM, Google, ArcGIS, Photon etc.)
  • googlemaps: interface para a API do Google Maps
  • ArcGIS API for Python: utiliza o serviço de geocodificação do ArcGIS
  • opencage: cliente do serviço OpenCage

Release files for geocodebr 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for geocodebr 0.1.0
File Size Uploaded
geocodebr-0.1.0.tar.gz 175.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for geocodebr 0.1.0
File Interpreter ABI Platform
geocodebr-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 223.3 kB

Release files / geocodebr-0.1.0.tar.gz

Download URL geocodebr-0.1.0.tar.gz
Size 175.9 kB
Tags Source
SHA-256 checksum
How to use checksums
59b751b626e22ad6fa885fb2328fd86a61e13fd15cbd15666c347d23afbc236f
BLAKE2b-256 checksum
How to use checksums
f45206fd7c6cff39686570716f4caf293bf5d371cca568e5a022280578b16873
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 22, 2026.

Transparency log

Release files / geocodebr-0.1.0-py3-none-any.whl

Download URL geocodebr-0.1.0-py3-none-any.whl
Size 47.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a1e010ece7c1264b129061919a169ca6c0880c94167ca2b28b1614c3dcc1d6eb
BLAKE2b-256 checksum
How to use checksums
b051c692742a2b8806ab97548136ca99b8d425182ff4f3eeaf2ded3ea8fd5a55
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 22, 2026.

Transparency log

Release history Release notifications | RSS feed

0.1.1

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page