Capítulo 3, Ambiente
Notebooks, scripts e o fluxo de trabalho
Análise de dados é exploração: você testa uma ideia, olha o resultado e decide o próximo passo. Os notebooks existem para esse ciclo, e têm uma armadilha que todo mundo cai uma vez.
Código deste capítulo: ambiente/cap03_notebooks.py
Script ou notebook
Um script roda de cima para baixo, do começo ao fim, toda vez. Isso é ótimo para um programa que você vai executar no servidor, mas ruim para explorar dados, porque reprocessar tudo para olhar uma coluna é lento. Um notebook é dividido em células que você executa uma de cada vez, e o resultado fica visível logo abaixo, como em um caderno de laboratório.
| Opção | Quando eu uso |
|---|---|
| JupyterLab | Exploração local, o padrão da área |
| Jupyter no VS Code | Notebook dentro do mesmo editor onde escrevo o resto do código |
| Google Colab | Quando não quero instalar nada, ou preciso de GPU |
| Script comum | Quando o código vai virar rotina, teste ou serviço |
Para usar o JupyterLab em um projeto com uv, instale-o como dependência de desenvolvimento e abra:
uv add --dev jupyterlab ipykernel
uv run jupyter lab
O kernel e a armadilha do estado escondido
Cada notebook é ligado a um kernel, o processo Python que lembra de todas as variáveis que você criou. As células não precisam rodar em ordem: você pode executar a quinta, voltar e reexecutar a segunda. É exatamente isso que causa o problema. O notebook pode mostrar um resultado que só existe por causa de uma célula que você editou depois, e o texto que você lê na tela não reproduz mais o resultado:
celulas = ["total = 10", "dobro = total * 2"]
kernel = {}
for celula in celulas:
exec(celula, kernel)
celulas[0] = "total = 99"
exec(celulas[0], kernel)
print("o que a tela mostra:", kernel["dobro"])
novo_kernel = {}
for celula in celulas:
exec(celula, novo_kernel)
print("depois de reiniciar e rodar tudo:", novo_kernel["dobro"])
o que a tela mostra: 20
depois de reiniciar e rodar tudo: 198
Eu editei a primeira célula para 99 e reexecutei só ela. O dobro na tela continuou 20, um valor que não corresponde mais ao código visível. Só ao reiniciar o kernel e rodar tudo em ordem aparece o valor verdadeiro, 198.
A regra antes de chamar um notebook de pronto
Reinicie o kernel e execute todas as células, em ordem. Se algo quebrar ou mudar, o notebook dependia de um estado escondido. Eu faço isso antes de compartilhar qualquer notebook.
O melhor dos dois mundos: células em um arquivo `.py`
O VS Code e o JupyterLab (com a extensão jupytext) entendem um arquivo Python comum com marcadores # %%: cada marcador abre uma célula. O arquivo continua sendo um script que roda inteiro, com a vantagem de diferenças legíveis no Git, o que o formato .ipynb (um JSON gigante com saídas embutidas) não dá:
# %% [markdown]
# # Notas de vendas
# Cada bloco `# %%` é uma célula no VS Code e no JupyterLab (com jupytext).
# %%
import numpy as np
vendas = np.array([120.0, 80.5, 99.9, 150.0])
# %%
print(vendas.mean().round(2))
# %%
print(vendas.max())
Medir tempo no notebook
No Jupyter, a "mágica"
%timeitroda o código várias vezes e devolve uma média confiável, muito melhor do que umtime.time()isolado. Em um script comum, o equivalente é o módulotimeit, que o capítulo 18 usa.