SQL vs Pandas - Operações Básicas parte 2
Neste artigo vamos continuar fazendo uma comparação entre operações feitas no SQL e como fazer as mesmas utilizando o Pandas. Este artigo é uma continuação desta postagem
SQL vs Pandas - Operações Básicas
Vamos nos aprofundar em outras operações básicas, como unir dados, melhorar critérios de pesquisa, agrupamento de dados e pesquisa por datas, entre outros assuntos.
O que você vai aprender neste artigo?
* Atualizando dados.
* Excluir dados.
* Unindo dois conjuntos de dados com a mesma estrutura.
* Trabalhando com JOINS.
* Criando novas colunas.
* Operadores lógicos nas consultas.
* Trabalhando com valores nulos.
* Agrupamento de dados.
* Pesquisando Datas.
* Criando uma coluna com valor condicional.
* Extraindo dia, mês e ano de uma data.
ATUALIZANDO DADOS
Para a atualizãção de dados no SQL utilizamos a cláusula UPDATE. No exemplo a seguir temos uma tabela produtos e vamos reajustar os preços em 20% dos produtos que tenham seu preco menor que 30.
UPDATE produtos SET preco = preco * 1.2 WHERE preco < 30
Se tivermos um dataset com a mesma estrutura, podemos atualizar dados utilizando o método loc.
dataset.loc[dataset["preco"] < 30, "preco"] *= 1.20
EXCLUIR DADOS
Para excluir registros o SQL utiliza a cláusula DELETE
DELETE FROM produtos WHERE preco < 10
No Pandas para eliminar linhas podemos criar um novo Dataset, mantendo apenas as linhas que queremos
dataset = dataset.loc[dataset["preco"] < 10]
UNINDO DOIS CONJUNTOS DE DADOS COM A MESMA ESTRUTURA
Quando possuimos várias tabelas com a mesma estrutura e desejamos juntar ambas para compor um único conjunto de dados o SQL utiliza a cláusula UNION. O número de colunas utilizando em ambas as tabelas deve ser igual e e as colunas devem ter o mesmo tipo de dados
No exemplo a seguir temos duas tabelas alunos, com a mesma estrutura
SELECT nome, email FROM alunos_capital
UNION
SELECT nome, email FROM alunos_interior
No Pandas, para fazer a mescla de dois datasets utilizamos o método concat de nossa instância do Pandas.
pd.concat([alunos_capital, alunos_interior]).drop_duplicates()
TRABALHANDO COM JOINS
No SQL utilizamos JOIN para estabelecer vínculos entre diferentes tabelas que tenham campos em comum. Os tipos mais comuns de JOINs são
INNER JOIN - Retorna dados em comum entre as duas tabelas
RIGHT JOIN - Retorna dados considerando todos os registros da tabela da direita.
LEFT JOIN - Retorna dados considerando todos os registros da tabela da esquerda.
Vamos começar vendo como funciona o INNER JOIN. Como comentamos, ele retorna dados que existam em ambas as tabelas vinculadas. Como exemplo, vamos considerar a seguinte estrutura:
Vendas
- codigo_venda
- data
- codigo_produto
- quantidade
- valor_vendido
Produtos
- codigo
- nome
- valor
Nosso objetivo é retornar os produtos vendidos. Como podemos ver, o código do produto fica na tabela de vendas, mas o nome fica na tabela de produtos. Neste caso, um INNER JOIN é necessário
SELECT * FROM Vendas
INNER JOIN Produtos
ON Vendas.codigo_produto = Produtos.codigo
No Pandas podemos usar o método merge da sua instância do Pandas, neste métodos informamos os datasets e a forma de vincular as informações:
pd.merge(Vendas, Produtos, left_on="codigo_produto", right_on="codigo")
Mas e se quisermos saber os produtos não vendidos? Neste caso precisamos pegar todos os produtos que não existam na tabela de vendas. Podemos usar um RIGHT JOIN para chegar neste resultado
SELECT * FROM Vendas
RIGHT JOIN Produtos
ON Vendas.codigo_produto = Produtos.codigo
No Pandas podemos também utilizar o método merge com um parâmetro a mais chamado how, informando a forma de vínculo.
pd.merge(Vendas, Produtos, left_on="codigo_produto", right_on="codigo", how="right")
CRIANDO NOVAS COLUNAS
Para criar novas colunas durante o processo de consulta podemos fazer o seguinte no SQL:
SELECT nome, valor, valor *0.80 as desconto from produtos
Neste exemplo, acrescentamos em nossa consulta feita na tabela de produtos uma coluna chamada desconto, que terá um valor 80% menor do que o valor atual do campo valor. A sintaxe foi
SELECT <<condicao>> AS <<nome_do_novo_campo>>
No Pandas podemos atingir o mesmo resultado utlizando o método assign
dataframe.assign(desconto=dataframe["valor"] * 0.80)
OPERADORES LÓGICOS NAS CONSULTAS
Quando fazemos consultas pode ser necessário utilizar mais de uma campo e diferentes condições. No SQL utilizamos para isso os operadores lógicos AND e OR. Veja os exemplos a seguir:
SELECT * FROM produtos WHERE categoria = "papelaria" AND valor > 50
SELECT * FROM produtos WHERE categoria = "papelaria" OR valor > 50
No Pandas podemos atingir o mesmo resultado da seguinte forma:
dataset[(dataset["categoria"] == "papelaria") & (dataset["valor"] > 50)]
dataset[(dataset["categoria"] == "papelaria") | (dataset["valor"] > 45)]
Perceba que no Pandas utilizandos o operador "&" como AND e o "|" como OR.
TRABALHANDO COM VALORES NULOS
No SQL utilizamos IS NULL e IS NOT NULL para fazer consultas utilizando NULL.
SELECT * FROM produtos WHERE desconto IS NULL
SELECT * FROM produtos WHERE desconto IS NOT NULL
No Pandas podemos utilizar respectivamente os métodos isna() e notna()
dataset[dataset["desconto"].isna()]
dataset[dataset["desconto"].notna()]
AGRUPAMENTO DE DADOS
Tivemos a oportunidade de ver no artigo anterior que no SQL utilizamos GROUP BY para o agrupamento de resultados
SELECT categoria, COUNT(*) FROM produtos GROUP BY categoria
O mesmo resultado pode ser obtido no Pandas utilizando o método groupby
dataset.groupby("categoria").size()
Você deve ter notado que no SQL utilizamos uma função de agregação chamada COUNT e no Pandas utilizamos o método size(). Existe também um método count(), mas o seu comportamento é diferente, ele se aplica a todas as colunas do dataset
dataset.groupby("categoria").count()
PESQUISANDO DATAS
A pesquisa de campos date ou datetime no SQL pode ser feita utilizando os operadores de comparação. Veja a seguir alguns exemplos de pesquisar por datas
SELECT * from Vendas WHERE data > "2023-10-24 00:00:00"
SELECT * from Vendas WHERE data > "2023-10-01 00:00:00" and data < "2023-10-24 00:00:00"
Perceba que o último exemplo não ficou muito bom. Poderiamos deixar a consulta mais fácil de ler utilizando o operador BETWEEN
SELECT * from Vendas WHERE data BETWEEN "2023-10-01 00:00:00" and "2023-10-24 00:00:00"
No Pandas pode ser necessário converter a sua coluna data antes de fazer a pesquisa. Sua instância do Pandas tem um método chamado to_datetime que permite fazer a conversão para qualquer formato de data.
dataset["data"] = pd.to_datetime(dataset["data"], format="%Y-%m-%d")
Uma vez convertido o campo em data, as pesquisas que fizemos podem ser repetidas no Pandas da seguinte forma:
dataset.loc[(dataset["data"] >= "2023-10-01")]
dataset.loc[(dataset["data"] >= "2023-10-01") & (dataset["data"] < "2023-10-24")]
CRIANDO UMA COLUNA COM VALOR CONDICIONAL
No SQL utilizamos a instrução CASE quando queremos criar uma coluna com valor condicional. No exemplo a seguir vamos criar uma coluna chamada faixa, que vai rotular os produtos de acordo com o seu valor
SELECT nome, valor,
CASE
WHEN valor < 10 THEN "Barato"
WHEN valor < 50 THEN "Normal"
WHEN valor > 50 THEN "Caro"
END as faixa
FROM produtos
Para fazer isso no Pandas podemos instalar um novo pacote no Python chamado NumPy. O NumPy possui um método chamado where que nos permite criar isso
import numpy as np
dataset["faixa"] = np.where(dataset["valor"]<10, "Barato",
np.where(dataset["valor"]<50, "Normal", "Caro"))
Perceba que o método where no NumPy recebe 3 parâmetros, o primeiro é a condição, o segundo é o valor que deve ser utilizado caso a condição seja verdadeira e o último parâmetro é o valor se a condição for falsa.
EXTRAINDO DIA, MÊS E ANO DE UMA DATA
No SQL podemos utilizar as funções DAY, MONTH e YEAR para extrair informações de dia, mês e ano de um campo do tipo date ou datetime
SELECT data, day(data) as dia, month(data) as mes, year(data) as ano FROM Vendas
Para fazer o mesmo no Pandas, primeiro precisamos converter o nosso campo em date usando o método to_datetime do Pandas.
dataset["data"] = pd.to_datetime(dataset["data"], format="%Y-%m-%d")
Uma vez convertido o campo, podemos criar estes novos campos utilizando os métodos dt.day, dt.month e dt.year.
dataset["dia"]=dataset["data"].dt.day
dataset["mes"]=dataset["data"].dt.month
dataset["ano"]=dataset["data"].dt.year