Series, DataFrames e índices
Construir tabelas, inspecionar tipos, ler CSV e compreender alinhamento por rótulos.
Uma Series é uma sequência de valores com rótulos. Um DataFrame é uma tabela com colunas e um índice de linhas. Cada coluna pode ter um tipo diferente. O índice identifica as linhas nas operações de seleção e alinhamento.
Construir uma tabela
import pandas as pd
vendas = pd.DataFrame({
"cidade": ["Porto", "Porto", "Braga", "Braga"],
"produto": ["pão", "leite", "pão", "arroz"],
"quantidade": [2, 3, 5, 4],
"preco": [1.5, 1.2, 1.5, 2.0],
})
print(vendas.to_string(index=False))
print(vendas.shape)
print(vendas.dtypes)Dados de entrada
Há quatro observações e quatro colunas, por isso shape é (4, 4). Cada linha representa uma venda. Quantidade é uma contagem; preço é o preço por unidade em euros. Ainda não há uma coluna de total.
vendas["quantidade"] devolve uma Series. vendas[["quantidade"]] devolve um DataFrame com uma coluna. A diferença afeta a forma e as operações seguintes.
pd.Series([10, 20], index=["a", "b"]) associa 10 a a e 20 a b. A série não é apenas um array com uma legenda: os rótulos participam nas operações.
Inspecionar antes de transformar
| Operação | Pergunta |
|---|---|
df.head(3) | Como são as primeiras três linhas? |
df.tail(3) | Como termina a tabela? |
df.shape | Quantas linhas e colunas tem? |
df.columns | Que nomes têm as colunas? |
df.index | Como estão identificadas as linhas? |
df.dtypes | Que tipo tem cada coluna? |
df.info() | Quantos valores não nulos existem e que tipos há? |
info() escreve informação e devolve None. Os tipos de strings podem aparecer como object, string ou str, consoante a versão e a construção. Confere operações e significado dos valores, não apenas o nome visual do tipo.
Ler um CSV
vendas = pd.read_csv("vendas.csv", sep=";", decimal=",")
sep indica o separador dos campos. decimal indica o separador decimal dentro de valores numéricos. dtype={"codigo": "string"} evita que um código como "0012" perca os zeros iniciais. usecols lê apenas as colunas necessárias e parse_dates pode interpretar colunas de datas, mas confere o formato recebido.
No navegador, os exemplos usam StringIO e dados visíveis. Num notebook local, substitui esse objeto pelo caminho do ficheiro. Exporta uma tabela com df.to_csv("resultado.csv", index=False) se o índice não fizer parte dos dados; sem esse argumento, pandas escreve-o como mais uma coluna.
O alinhamento usa rótulos
import pandas as pd
a = pd.Series([10, 20], index=["Porto", "Braga"])
b = pd.Series([1, 2], index=["Braga", "Porto"])
print((a + b).sort_index().to_dict())
c = pd.Series([3], index=["Aveiro"])
print(a.add(c, fill_value=0).sort_index().to_dict())Dados de entrada
O primeiro resultado é Braga 21 e Porto 12. Não somamos a primeira posição à primeira posição: somamos os valores da mesma cidade. Quando um rótulo só está num dos lados, a operação normal produz um valor em falta nesse rótulo. fill_value=0 é adequado aqui apenas porque interpretamos a ausência como nenhuma quantidade para acrescentar.
Tornar o índice explícito
df.set_index("codigo") devolve uma tabela com essa coluna como índice. reset_index() devolve o índice para uma coluna e cria posições de zero em diante. Um índice pode ter valores repetidos. Se o problema exige uma chave única, verifica df.index.is_unique ou df["codigo"].is_unique em vez de o assumir.
Exercícios
Somar pelo rótulo
a tem Porto: 10 e Braga: 20. b tem Braga: 1 e Porto: 2. Quanto vale (a + b) no rótulo Porto?
Primeira pista
Mais uma pista
Ver solução
O resultado é 12. Braga recebe 20 + 1 = 21, mesmo aparecendo noutra posição de b.
Erros frequentes
Escolher Series ou DataFrame
Qual é a expressão que conserva a coluna x como um DataFrame de uma coluna?
Primeira pista
Mais uma pista
Mesmo com um único nome, os parênteses retos interiores criam a lista.
Ver solução
df[[“x”]] devolve um DataFrame. A sua forma é número de linhas por uma coluna.
- df[["x"]]. A lista de colunas conserva uma tabela.
- df["x"]. Seleciona uma Series.
- df.loc["x"]. Procura um rótulo de linha, não esta seleção de coluna.
Erros frequentes
Tratar as duas seleções como sempre equivalentes nas operações seguintes.