Análise de dados
Carregar, limpar, agregar e descrever — o caminho de um conjunto de dados até a resposta.
Analisar dados é sempre a mesma sequência: carregar, conferir, limpar, agregar, responder. A linguagem traz as cinco etapas, e esta página é o caminho inteiro com um conjunto pequeno o bastante para caber na tela.
O quadro de dados#
Arcane.Analytics trabalha com um frame: um cluster de vaults, que é o que IO.read_csv(caminho, yes) devolve e o que Database.query devolve.
adopt Arcane.Analytics as An
vendas := [
{"produto": "cafe", "regiao": "sul", "valor": 120.0, "qtd": 4},
{"produto": "cafe", "regiao": "norte", "valor": 90.0, "qtd": 3},
{"produto": "cha", "regiao": "sul", "valor": 60.0, "qtd": 2},
{"produto": "cha", "regiao": "norte", "valor": 45.0, "qtd": 1},
{"produto": "acucar", "regiao": "sul", "valor": 30.0, "qtd": 5}
]
out len(vendas), "registros"1. Conferir antes de confiar#
A primeira coisa a fazer com um conjunto novo não é calcular — é olhar. Quantas linhas, quais colunas, o que está faltando:
adopt Arcane.Analytics as An
action colunas_de(dados):
yield keys(dados[0])
action faltando(dados, coluna):
yield len([l cycle l in dados given (l[coluna] ?? void) is void])
out colunas_de(vendas)
out faltando(vendas, "valor"), "sem valor"2. Limpar#
action limpo(dados):
yield [linha cycle linha in dados
given (linha["valor"] ?? 0.0) > 0.0]
action com_total(dados):
yield [linha with {"total": linha["valor"] * linha["qtd"]}
cycle linha in dados]Note que nada é mutado: cada etapa devolve um frame novo. É o que permite comparar o antes e o depois, e é o que faz um pipeline ser reexecutável.
3. Agregar#
action somar_por(dados, chave, campo):
totais := {}
cycle linha in dados:
grupo := linha[chave]
totais[grupo] := (totais[grupo] ?? 0.0) + linha[campo]
yield totais
out somar_por(vendas, "produto", "valor")
out somar_por(vendas, "regiao", "valor"){cafe: 210.0, cha: 105.0, acucar: 30.0}
{sul: 210.0, norte: 135.0}O vault como acumulador é O(n): uma passada, e cada escrita é constante. A versão "óbvia" — para cada grupo, percorrer tudo filtrando — é O(n × grupos), e o `dataforge big-o` acusa.
4. Descrever#
adopt Arcane.Analytics as An
valores := [v["valor"] cycle v in vendas]
out An.media(valores)
out An.mediana(valores)
out An.desvio_padrao(valores)
out min(valores), max(valores)Média e mediana juntas dizem mais que qualquer uma sozinha. Quando as duas se afastam, há assimetria — um valor muito alto puxando a média —, e é o sinal de que a média não representa o conjunto.
5. Responder, e mostrar#
O resultado de uma análise termina de três formas, e cada uma tem o seu lugar:
| Onde termina | Com o quê |
|---|---|
| no terminal | out, ou o pacote `tabela` |
| num arquivo | IO.write_csv, IO.write_json, `Arcane.Excel` |
| numa página | Vitrine — o mesmo .df vira painel com gráfico |
Quando os dados não cabem na memória#
A regra prática: até alguns milhões de linhas, um cluster de vaults resolve. Acima disso, há três caminhos, e o primeiro costuma bastar:
- Processar por partes, com
stream action—O(1)de espaço, ver complexidade de espaço. - Deixar o banco agregar —
SUMeGROUP BYacontecem onde o dado já está, e volta só o resultado. Ver SQLite. - A ponte para o Python —
adopt Python.pandas as pdquando a conta é vetorizada e o volume justifica.
adopt Python.numpy as np
a := np.array([1.0, 2.0, 3.0])
out (a * 2).tolist() // a conta é do numpy, sem cópia na fronteira