Ciência de dados com pandas
A ciência de dados é um campo multidisciplinar e muito importante nos nossos dias. Ela tem como objetivos descobrir anomalias e padrões escondidos em grandes quantidades de dados (“Big Data”) através de técnicas de modelagem e análise. Em postagens anteriores, exploramos a área através da biblioteca pandas. Neste post, terminaremos nossa exploração apresentando os métodos do pandas voltados para manipulação e transformações de dados. Este post assume familiaridade com os conceitos apresentados anteriormente (aqui, aqui e aqui).
Manipulações de dados com pandas
Para acompanhar nossa exploração do pandas, é preciso importar a biblioteca num código Python.
				
					import pandas as pd
 
				
			Também precisaremos de alguns dados. Começaremos com os dados abaixo. Para usá-los, basta copiá-los no seu arquivo Python.
				
					data = {
    'Estado': ['SP', 'RJ', 'RS', 'SP', 'CE', 'RJ', 'CE'],
    'Produto': ['A', 'B', 'A', 'C', 'A', 'B', 'C'],
    'Vendas': [100, 50, 120, None, 80, None, 40],
    'Mês': ['Jan', 'Jan', 'Fev', 'Fev', 'Jan', 'Fev', 'Fev']
}
 
				
			Como explicado anteriormente, os dados precisam ser abertos com o pandas.
				
					df = pd.DataFrame(data) 
				
			Nossos dados possuem valores ausentes (None). Usaremos o comando fillna() para substituí-los por zeros.
				
					df_preenchido = df.fillna(0) 
				
			groupby()
Nossa primeira exploração será do comando groupby(). Uma operação groupby pode envolver múltiplas tarefas combinadas, como dividir dados, aplicar cálculos e recombinar os resultados. Essa é uma forma conveniente para agrupar grandes quantidades de dados e, simultaneamente, realizar computação nesses grupos. Na prática, o método groupby() não modifica o DataFrame, ele apenas cria um objeto groupby de agregação. Essa agregação é comumente usada para realizar operações subsequentes concisamente. No exemplo abaixo, usamos o comando groupby sobre nossos dados para verificar a média de vendas por estado. Veja que as colunas são diretamente selecionadas por seus nomes.
				
					# agrupa por estado e acha a média de vendas
media_vendas_por_estado = df_preenchido.groupby('Estado')['Vendas'].mean()
print(media_vendas_por_estado) 
				
			
				
					Estado
CE     60.0
RJ     25.0
RS    120.0
SP     50.0
Name: Vendas, dtype: float64 
				
			Abaixo, um exemplo de agrupamento mais complexo. Nesse exemplo, o groupby é usado para agregar as vendas nos estados por mês e depois calcular sua soma.
				
					
# agrupa por estado e mês para obter a soma de vendas
sales_by_product_month = df_preenchido.groupby(['Produto', 'Mês'])['Vendas'].sum()
print(sales_by_product_month) 
				
			
				
					Produto  Mês
A        Fev    120.0
         Jan    180.0
B        Fev      0.0
         Jan     50.0
C        Fev     40.0
Name: Vendas, dtype: float64 
				
			O groupby também pode ser usado com múltiplas operações agregadas. Para isso, no exemplo abaixo, o groupby é usado em combinação com agg(). O agg() aplica uma lista de funções sobre os elementos agregados. Aplicaremos três funções para calcular o mínimo de vendas (min), máximo de vendas (max) e a contagem de meses com vendas para cada estado.
				
					
# agrupa por estado e acha dados estatísticos sobre as vendas
estat_vendas_por_estado = df_preenchido.groupby('Estado')['Vendas'].agg(['min', 'max', 'count'])
print(estat_vendas_por_estado) 
				
			
				
					
          min    max  count
Estado                     
CE       40.0   80.0      2
RJ        0.0   50.0      2
RS      120.0  120.0      1
SP        0.0  100.0      2 
				
			O groupby também pode ser usado com funções personalizadas. No exemplo abaixo, utilizamos groupby com uma função que retorna o máximo de vendas para cada estado.
				
					def top_estado_vendas(group):
    return group.nlargest(1).iloc[0]  # Retorna valor máximo de vendas por estado
resultados = df_preenchido.groupby('Estado')['Vendas'].apply(top_estado_vendas)
print(resultados) 
				
			Na função acima, note que usamos o iloc combinado com nlargest() para retornar especificamente o valor (iloc) máximo (nlargest) encontrado. Os resultados obtidos:
				
					Estado
CE     80.0
RJ     50.0
RS    120.0
SP    100.0
Name: Vendas, dtype: float64 
				
			sort_value()
O comando sort_value() organiza um DataFrame a partir da ordem (ascendente ou descendente) de uma ou mais colunas. Abaixo, ele é utilizado para organizar nossos dados a partir dos valores de vendas.
				
					# ordena dados pelos valores de Vendas
df_reordenado = df_preenchido.sort_values(by=['Vendas'])
print(df_reordenado) 
				
			
				
					  Estado Produto  Vendas  Mês
3     SP       C     0.0  Fev
5     RJ       B     0.0  Fev
6     CE       C    40.0  Fev
1     RJ       B    50.0  Jan
4     CE       A    80.0  Jan
0     SP       A   100.0  Jan
2     RS       A   120.0  Fev 
				
			A opção default do sort_value() organiza os dados de maneira ascendente. Mas ela é facilmente alterada com a opção ascending=False.
				
					# ordena dados pelos valores de Vendas em ordem decrescente
df_reordenado = df_preenchido.sort_values(by=['Vendas'], ascending=False)
print(df_reordenado) 
				
			Note que, nos resultados abaixo, o pandas reordenou os dados, mas manteve os índices originais. Quando isso não é desejado, basta adicionar no comando sort_values a opção ignore_index=True.
				
					  Estado Produto  Vendas  Mês
2     RS       A   120.0  Fev
0     SP       A   100.0  Jan
4     CE       A    80.0  Jan
1     RJ       B    50.0  Jan
6     CE       C    40.0  Fev
3     SP       C     0.0  Fev
5     RJ       B     0.0  Fev 
				
			concat()
Em ciência de dados ou mesmo durante a obtenção e preparação de dados para treinamento de algoritmos de machine learning, a combinação de múltiplos conjuntos é uma atividade corriqueira. Como os conjuntos tendem a ser grandes, ninguém deve fazer isso manualmente. O pandas simplifica essa tarefa com o comando concat(). Ele faz o óbvio: combina múltiplos conjuntos de dados em um. Para nosso exemplo, criamos um novo conjunto para ser combinado com o anterior. Antes da combinação, fizemos novamente a substituição de valores ausentes por zero com fillna().
				
					data2 = {
    'Estado': ['ES', 'AM', 'PA', 'ES', 'AM', 'RJ'],
    'Produto': ['C', 'A', 'B', 'B', 'B', 'C'],
    'Vendas': [80, None, 20, 10, 50, 25],
    'Mês': ['Mar', 'Abr', 'Fev', 'Abr', 'Mar', 'Mar']
}
df2 = pd.DataFrame(data2)
df_preenchido2 = df2.fillna(0)
# concatena os conjuntos df_preenchido e df_preenchido2
dados_completos = pd.concat([df_preenchido, df_preenchido2], ignore_index=True)
print(dados_completos) 
				
			No trecho acima, a opção ignore_index=True ignora os índices dos conjuntos que estão sendo combinados e cria um novo índice no conjunto final mostrado abaixo.
				
					   Estado Produto  Vendas  Mês
0      SP       A   100.0  Jan
1      RJ       B    50.0  Jan
2      RS       A   120.0  Fev
3      SP       C     0.0  Fev
4      CE       A    80.0  Jan
5      RJ       B     0.0  Fev
6      CE       C    40.0  Fev
7      ES       C    80.0  Mar
8      AM       A     0.0  Abr
9      PA       B    20.0  Fev
10     ES       B    10.0  Abr
11     AM       B    50.0  Mar
12     RJ       C    25.0  Mar 
				
			apply()
A funcionalidade apply() é uma das mais úteis do pandas para tarefas de machine learning. Ela é particularmente útil para pré-processamentos de dados e é frequentemente usada, inclusive com dados de textos, para processamento de linguagem natural. Em essência, o comando apply() aplica funções diretamente num DataFrame ou (mais comum) em colunas ou linhas específicas.
No trecho abaixo, criamos uma função que calcula o lucro sobre nossas vendas. Ela é diretamente aplicada nos dados (coluna Vendas) e já cria uma nova coluna com os resultados.
				
					
def calcula_lucro(vendas, margem=0.3):
    return vendas * margem
# aplica função que calcula o lucro sobre as vendas
dados_completos['Lucro'] = dados_completo['Vendas'].apply(calcula_lucro) 
print(dados_completos) 
				
			Os resultados com uma nova coluna (Lucro).
				
					   Estado Produto  Vendas  Mês  Lucro
0      SP       A   100.0  Jan   30.0
1      RJ       B    50.0  Jan   15.0
2      RS       A   120.0  Fev   36.0
3      SP       C     0.0  Fev    0.0
4      CE       A    80.0  Jan   24.0
5      RJ       B     0.0  Fev    0.0
6      CE       C    40.0  Fev   12.0
7      ES       C    80.0  Mar   24.0
8      AM       A     0.0  Abr    0.0
9      PA       B    20.0  Fev    6.0
10     ES       B    10.0  Abr    3.0
11     AM       B    50.0  Mar   15.0
12     RJ       C    25.0  Mar    7.5 
				
			A opção default do comando apply() realiza os cálculos de uma função em uma ou mais colunas, mas isso pode ser mudado com a opção axis=1. Nesse caso, a função será aplicada nas linhas.
No trecho abaixo, nossa nova função tem um condicional que classifica o volume de vendas. Ela é diretamente aplicada nos dados, mas especificamente sobre suas linhas.
				
					def categoriza_vendas(row):
    if row['Vendas'] > 100:
        return 'Alto'
    elif row['Vendas'] > 50:
        return 'Médio'
    else: 
        return 'Baixo'  
# aplica função que categoriza as vendas
dados_completos['Desempenho das Vendas'] = dados_completos.apply(categoriza_vendas, axis=1) 
#print(dados_completos) 
				
			
				
					   Estado Produto  Vendas  Mês  Lucro Desempenho das Vendas
0      SP       A   100.0  Jan   30.0                 Médio
1      RJ       B    50.0  Jan   15.0                 Baixo
2      RS       A   120.0  Fev   36.0                  Alto
3      SP       C     0.0  Fev    0.0                 Baixo
4      CE       A    80.0  Jan   24.0                 Médio
5      RJ       B     0.0  Fev    0.0                 Baixo
6      CE       C    40.0  Fev   12.0                 Baixo
7      ES       C    80.0  Mar   24.0                 Médio
8      AM       A     0.0  Abr    0.0                 Baixo
9      PA       B    20.0  Fev    6.0                 Baixo
10     ES       B    10.0  Abr    3.0                 Baixo
11     AM       B    50.0  Mar   15.0                 Baixo
12     RJ       C    25.0  Mar    7.5                 Baixo 
				
			Conclusões
Com esse post, encerramos nossa exploração do pacote pandas. Mas não pense que fomos muito longe. O pandas é um pacote enorme, fácil de usar e extremamente poderoso. Por isso, se você tem interesse em machine learning, inteligência artificial ou ciência de dados, confira a documentação oficial e busque aprender mais sobre ele.