# Reestruturar com pivot, melt e stack

Converter tabelas longas e largas e reconhecer quando a chave exige agregação.

Página: https://resumos.rgo.pt/cadeiras/ct-iadp/reestruturar/

A mesma informação pode ocupar tabelas com formas diferentes. No formato **longo**, uma variável identifica o produto e outra guarda a quantidade. No formato **largo**, cada produto pode ser uma coluna. Reestruturar muda a disposição, mantendo os valores quando a correspondência é única.

## Longo para largo com pivot

```python
import pandas as pd
longa = pd.DataFrame({
    "cidade": ["Porto", "Porto", "Braga", "Braga"],
    "produto": ["pão", "leite", "pão", "leite"],
    "quantidade": [2, 3, 5, 1],
})
larga = longa.pivot(index="cidade", columns="produto", values="quantidade")
print(larga.to_string())
reconstruida = larga.reset_index().melt(id_vars="cidade", var_name="produto", value_name="quantidade")
print(reconstruida.sort_values(["cidade", "produto"]).to_string(index=False))
```

A linha Porto passa a ter leite 3 e pão 2; a linha Braga tem leite 1 e pão 5. `index` escolhe os identificadores das linhas; `columns` os valores que se tornam nomes de colunas; `values` a medida que preenche cada célula.

Para `pivot`, cada par cidade-produto precisa de um único valor. Se houver duas vendas de pão no Porto, a posição correspondente tem dois candidatos e pandas lança um erro. A tabela precisa primeiro de uma decisão: somar as vendas, calcular a média ou conservar outra dimensão que as distinga.

## Largo para longo com melt

`melt` conserva as colunas `id_vars` e transforma as restantes em pares variável-valor. `var_name` dá nome à coluna que guarda o nome antigo da medida. `value_name` dá nome à coluna que guarda o valor.

Se a tabela tem datas e quantidades por produto:

```
longa = larga.melt(
    id_vars="data",
    value_vars=["pão", "leite"],
    var_name="produto",
    value_name="quantidade",
)
```

Cada linha inicial origina duas linhas, uma por produto. Não duplicámos observações da mesma medida; passámos a identificar a medida numa coluna. Conserva todos os identificadores necessários para voltar à forma original.

## stack e unstack

`stack` move um nível dos nomes de colunas para o índice de linhas. `unstack` move um nível do índice para as colunas. Isto produz ou usa um **MultiIndex**, um índice com vários níveis.

```
serie = longa.set_index(["cidade", "produto"])["quantidade"]
larga = serie.unstack("produto")
```

Agora o par cidade-produto identifica cada valor da Series. Ao deslocar produto para as colunas, cidade fica nas linhas. A ordenação e a preservação de valores em falta de `stack` mudaram entre versões; se o enunciado exigir uma forma exata, confere os argumentos da versão usada nas aulas.

## O que não é uma reestruturação

`df.T` troca linhas por colunas, mas não resolve uma chave duplicada nem calcula totais. `rename` muda nomes sem mudar a disposição. `merge` associa observações entre tabelas. `pivot_table`, na página seguinte, pode agregar vários valores na mesma célula.

Antes de escolher a operação, escreve que colunas identificam uma observação e qual é a medida. Depois confere o número de valores e uma célula concreta no resultado.

## Exercícios

Decidir quando agregar

Existem duas vendas de pão no Porto. Queres uma célula com a soma das quantidades desse par cidade-produto. Qual é a operação adequada?

Primeira pista

A chave da célula aparece mais de uma vez.

Mais uma pista

A soma faz parte do pedido e deve ser explícita.

Ver solução

pivot\_table(…, values=“quantidade”, aggfunc=“sum”) reúne as vendas. Não dependas da média por defeito.

*   **pivot\_table com aggfunc="sum".** Agrega os valores que têm o mesmo par de chaves.
*   **pivot sem agregação.** Exige um valor único para cada célula.
*   **rename.** Muda nomes, não reduz as duas vendas a uma célula.

#### Erros frequentes

Escolher pivot\_table sem indicar a agregação.

[Voltar à explicação](https://resumos.rgo.pt/cadeiras/ct-iadp/reestruturar/#longo-para-largo-com-pivot)

Contar a transformação

Uma tabela tem três datas e duas colunas de produto. melt conserva a data e transforma ambas as colunas. Quantas linhas há no resultado, sem eliminar nulos?

Primeira pista

Cada data dá uma observação para cada produto.

Mais uma pista

São três datas vezes dois produtos.

Ver solução

Há seis linhas. Cada uma identifica data, produto e quantidade.

#### Erros frequentes

Contar apenas as datas ou somar o número de datas ao de produtos.

[Voltar à explicação](https://resumos.rgo.pt/cadeiras/ct-iadp/reestruturar/#largo-para-longo-com-melt)
