Criar, alterar e limpar tabelas

Colunas calculadas, rename, drop, map, apply e tratamento explícito de valores em falta.

Perguntar sobre esta página

ChatGPTClaudePerplexityGeminiCopiar e abrir

Brain rot

A seguirPara ti

@resumos.feup

som original ·

Definições

Leitura

Mudar de trecho
Legendas
Mostrar no vídeo
Vídeos de fundo

O texto, o áudio e os teus vídeos ficam neste dispositivo.

Créditos dos vídeos e da voz

Partilhar página

Uma transformação deve dizer que valores muda e que informação conserva. Criar a coluna de total acrescenta um cálculo a cada linha. Apagar uma linha retira uma observação, por isso precisa de uma razão.

Criar uma coluna calculada

Guardar o total de cada venda
import pandas as pd
vendas = pd.DataFrame({
    "produto": ["pão", "leite", "arroz"],
    "quantidade": [2, 3, 4],
    "preco": [1.5, 1.2, 2.0],
})
vendas["total"] = vendas["quantidade"] * vendas["preco"]
vendas = vendas.rename(columns={"preco": "preco_unitario"})
print(vendas.round(2).to_string(index=False))
Dados de entrada

Os totais são 3,00, 3,60 e 8,00. A multiplicação é vetorizada, alinhada pelo índice. A atribuição de um escalar a uma coluna preenche todas as linhas; a atribuição de uma Series alinha os seus rótulos com o índice do DataFrame.

rename muda os nomes e devolve outra tabela por defeito. drop(columns=["preco_unitario"]) elimina uma coluna. drop(index=[rotulo]) elimina uma linha por rótulo. Escolhe columns ou index para evitar confundir o eixo.

Inserir, retirar e reordenar colunas

df.insert(1, "total", valores) insere a coluna na posição 1, antes da segunda coluna, e altera a tabela. O nome deve ser novo por defeito. Uma Series fornecida como valores alinha-se pelos rótulos do índice; uma lista deve ter o comprimento das linhas.

retirada = df.pop("total") remove a coluna e devolve-a como Series. del df["total"] remove-a sem devolver a coluna. drop(columns=["total"]) devolve outra tabela por defeito. Estas operações têm efeitos diferentes; não atribuas df = df.insert(...), porque insert devolve None.

Para reordenar, seleciona a lista de colunas pretendida. Para mudar todos os nomes, df.columns = [...] exige um nome por coluna, na ordem atual. df.columns.str.lower() transforma os nomes em minúsculas. Para alterar apenas alguns, rename(columns={...}) deixa os restantes intactos.

vendas = pd.DataFrame({"produto": ["pão", "leite"], "unidades": [2, 3]})
vendas.insert(1, "preco", [1.5, 1.2])
precos = vendas.pop("preco")
vendas = vendas[["unidades", "produto"]]
print(precos.to_list())      # [1.5, 1.2]
print(vendas.columns.to_list())  # ['unidades', 'produto']

Uma atribuição com df.loc[rotulo, ["produto", "unidades"]] = ["arroz", 4] muda as células indicadas. Se o rótulo não existe, pode criar uma linha, com ausência nas colunas não fornecidas. Para acrescentar muitas linhas, constrói uma tabela e usa concat.

map e apply

serie.map(dicionario) substitui valores através de uma correspondência. Valores sem correspondência ficam em falta, pelo que deves detetar chaves desconhecidas.

categorias = {"pão": "padaria", "leite": "laticínios"}
df["categoria"] = df["produto"].map(categorias)

serie.apply(funcao) aplica uma função a cada valor. df.apply(funcao, axis=1) chama a função para cada linha; com axis=0, para cada coluna. Prefere operações vetorizadas simples quando exprimem diretamente o cálculo. Usar apply para multiplicar duas colunas esconde uma operação que pandas já suporta.

Representar ausência

Uma célula em falta não é automaticamente zero. None, NaN, pd.NA e NaT podem representar ausência, dependendo do tipo. Usa isna() ou notna() para a detetar. Não uses valor == np.nan, porque NaN não é igual a si mesmo.

Ausência muda a interpretação
import pandas as pd
quantidades = pd.Series([2, None, 6], dtype="Float64")
print("em falta:", quantidades.isna().to_list())
print("conhecidos:", quantidades.count())
print("média conhecida:", quantidades.mean())
print("média se ausente = 0:", quantidades.fillna(0).mean())
print("soma toda ausente:", pd.Series([None, None], dtype="Float64").sum(min_count=1))
Dados de entrada

A média dos valores conhecidos é 4. Preencher com zero dá 8 / 3, cerca de 2,6667. São respostas a hipóteses diferentes. Na última linha, min_count=1 exige pelo menos um valor conhecido; sem isso, uma soma só de nulos pode dar zero.

Escolher uma política

dropna(subset=["quantidade"]) elimina linhas sem quantidade. fillna(0) substitui ausências por zero. Preencher pela média introduz valores estimados e reduz artificialmente a dispersão. Para um relatório, conserva a contagem de dados em falta e explica a hipótese usada.

ffill() propaga o valor anterior e bfill() o seguinte. Só fazem sentido quando a ordem está definida e a variável permite esse tipo de continuidade. Não propagues um preço entre produtos diferentes.

Um pd.NA isolado não pode ser tratado como verdadeiro ou falso. Algumas operações booleanas preservam a incerteza. Antes de filtrar, decide o destino das linhas cuja condição depende de dados ausentes.

Duplicados e integridade

duplicated(subset=["id"]) deteta repetições de um identificador. drop_duplicates conserva uma ocorrência conforme keep. Duas linhas iguais podem ser duas vendas reais; não as elimines apenas porque os valores coincidem. Usa a chave que identifica a observação e confere os totais antes e depois da limpeza.

Exercícios

Conservar o denominador correto

Uma Series Float64 tem 2, um valor ausente e 6. Quanto vale mean() sem preencher ausências?

Primeira pista
mean ignora normalmente os valores ausentes.
Mais uma pista
Há dois valores conhecidos cuja soma é 8.
Ver solução

A média conhecida é 8 / 2 = 4. Se preenchesses com zero, a pergunta e o denominador seriam diferentes.

Erros frequentes

Dividir por três ou interpretar a ausência automaticamente como zero.

Voltar à explicação
Atualizar a tabela certa

Queres alterar x para zero nas linhas em que x é negativo. Que expressão indica o destino da alteração numa única operação?

A tua resposta

Primeira pista
A atribuição precisa de atingir o original.
Mais uma pista

loc pode selecionar linhas e colunas na mesma operação.

Ver solução

Usa df.loc[mascara, “x”] = 0, depois de justificar que zero é a correção pretendida.

  • df.loc[df["x"] < 0, "x"] = 0. Seleciona as linhas e a coluna no próprio destino da atribuição.
  • df[df["x"] < 0]["x"] = 0. É uma atribuição encadeada a uma seleção intermédia.
  • df["x"] == 0. Compara valores e não altera a tabela.

Erros frequentes

Corrigir um sintoma de execução sem definir o significado da alteração.

Voltar à explicação

À tua maneira

Aparência

Modo de cor
Tema
Cor de destaque

Leitura

Fonte de leitura

Álgebra, lógica e uma ideia de cada vez.

Código

Fonte do código

CSS personalizado

Ativa uma sugestão ou guarda o teu CSS. Só muda este navegador.

Usa --page, --text e --accent para acompanhar o tema.

Seletores e recuperação

.site-header, .prose, .course-card, [data-reading-history], [data-playground] e .page-actions.

Abre a aparência com a tecla vírgula ou no rodapé. Se o CSS esconder os controlos, abre esta página sem CSS personalizado.

Pesquisar

Escreve para pesquisar em todo o site.

para escolher · Enter para abrir · Esc para fechar

Atalhos de teclado

Clica numa tecla para a mudar. Esc cancela. Backspace desativa.

PesquisarCtrl / Cmd K

Os atalhos não interferem enquanto escreves. Tab e Enter funcionam sempre.