Excel ou Pandas?

Alguns tantos exemplos de como manipular conjuntos de dados.

O famoso Pandas é um dos pacotes mais incríveis da linguagem Python e do PyData Stack. Sem dúvidas, é uma das principais ferramentas para cientistas de dados que trabalham com a linguagem Python.

De forma bem simples e resumida, o Pandas é um pacote para manipulação de dados. Imagine o Microsoft Excel, totalmente gratuito, altamente customizável e extremamente eficiente — isso é Pandas.

Notebook de estudo

Acesse o Jupyter Notebook para consultar os conceitos que serão abordados sobre manipulação de dados com Pandas em DataFrames.

Estruturas de Dados em Pandas

À primeira vista, o Pandas e o NumPy têm algumas semelhanças, principalmente na forma como criamos as estruturas de dados.

Contudo, o NumPy tem como principal objetivo a computação numérica, ou seja, trabalhamos com números em uma estrutura de dados unidimensional ou multidimensional e realizamos as operações de análise.

Já o Pandas, é bem mais abrangente, permite trabalhar com Séries Temporais e trabalhar com tabelas que podem conter qualquer tipo de dado e realizar uma série de operações com esses dados. Aqui, temos um resumo comparativo entre o Pandas e NumPy:

  • pandas.Series() — Objeto de1 Dimensão
  • pandas.DataFrame() — Objeto de 2 Dimensões
  • pandas.Panel() — Objetoo de 3 Dimensões
  • numpy.ndarray() — x Dimensões

A função Series, permite criar um objeto unidimensional; chamando a função DataFrame criamos um objeto de duas dimensões, uma matriz, trabela; a função Panel cria um objeto tridimensional.

Contudo, essas três estruturas podem ser feitas dentro de NumPy com a função ndarray, para criar qualquer número de dimensões. Inclusive, Pandas tem algumas limitações com a criação de dimensões, sendo possível gerar n dimensões com NumPy.

Importar bibliotecas

import pandas as pd
import numpy as np

Criar objeto do tipo Pandas

Veja que vamos criar um dicionário, abrindo e fechando chaves. Um dicionário é um conjunto de pares de chave:valor.

Abaixo, criamos valores com a função pd.series do Pandas. Veja que quando criamos objetos do tipo series unidimensional, passamos os valores junto a uma lista de índices, ou seja, definimos os índices que teremos para essa série de valores.

stock = 
{
'AMZN': pd.Series([346.15,0.59,459,0.52,589.8,158.88], index = ['Closing price','EPS','Shares Outstanding(M)','Beta', 'P/E','Market Cap(B)']),
'GOOG': pd.Series([1133.43,36.05,335.83,0.87,31.44,380.64],o
index = ['Closing price','EPS','Shares Outstanding(M)','Beta','P/E','Market Cap(B)']),
'FB': pd.Series([61.48,0.59,2450,104.93,150.92],
index = ['Closing price','EPS','Shares Outstanding(M)','P/E', 'Market Cap(B)']),
'YHOO': pd.Series([34.90,1.27,1010,27.48,0.66,35.36],
index = ['Closing price','EPS','Shares Outstanding(M)','P/E','Beta', 'Market Cap(B)']),
'TWTR':pd.Series([65.25,-0.3,555.2,36.23],
index = ['Closing price','EPS','Shares Outstanding(M)','Market Cap(B)']),
'AAPL':pd.Series([501.53,40.32,892.45,12.44,447.59,0.84],
index = ['Closing price','EPS','Shares Outstanding(M)','P/E','Market Cap(B)','Beta'])
}
#Dicionário pode ser um arquivo do tipo json:javascript object notation - padrão web

Se a estrutura acima parece ser muito estranha, saiba que um dicionário pode ser um arquivo do tipo JSON — JavaScript Object Notation que é o padrão amplamente usado na web. Se usarmos webscraping, para buscar dados de uma página web, é bem provável que se busque os dados no formato json.

Podemos extrair o arquivo, converter para DataFrame Pandas e teremos uma tabela com os dados para iniciar o trablaho de manipulação.

Verificar objeto

Para confirmar que estamos trabalhando com um dicionário, usamos a função type.

type(stock)
dict

Converter Dicionário para DataFrame

stock_df = pd.DataFrame(stock) 
stock_df
stock_df = pd.DataFrame(stock)

Automaticamente o Pandas detecta os nomes de colunas, os índices e os valores — inclusive os valores NaN.

Podemos ainda indicar quais serão os nomes dos índices no momento que criamos os DataFrames

Isso nos dá um poder imenso, porque depois podemos usar o nome dos índices para realizar o slicing através de regras com o nome das strings para fatiar o DataFrame.

Definir Índices

stock_df = pd.DataFrame(stock, 
index = [
'Closing price',
'EPS',
'Shares Outstanding(M)',
'P/E','Market Cap(B)',
'Beta']); stock_df
índices redefinios

Definir Colunas

Adicionando outro parâmetro, definimos os nomes das colunas passando uma lista de strings para definir o nome das colunas do DataFrame.

stock_df = pd.DataFrame(stock, 
index = [
'Closing price',
'EPS',
'Shares Outstanding(M)',
'P/E',
'Market Cap(B)',
'Beta'],
columns = ['FB','TWTR','SCNW']); stock_df

Se não encontrar uma correspondência entre o nome de coluna apontada e o DataFrame original, logo indica NaN como falta de correspondência.

Durante a manipulação de dados, o cientista de dados podeinadvertidamente, gerar NaN.

Chamar atributos do DataFrame

Vamos chamar o atributo index para listar os índices do DataFrame.

stock_df.indexIndex(['Closing price', 'EPS', 'Shares Outstanding(M)', 'P/E', 'Market Cap(B)','Beta'],dtype='object')

Assim como podemos chamar o atributo para listar as colunas

stock_df.columns
Index(['FB', 'TWTR', 'SCNW'], dtype='object')

Operações com DataFrames

Agora realizaremos operações com DataFrames. Vamos iniciar criando um dicionário referente a um quadro de medalhas de uma olimpíada.

Como chaves do dicionário temos o nome de países e como valor, dentro do dicionário, outro dicionário — dicionários aninhados.

Quadro_Medalhas_Olimpiada =
{
'USA' : {'Ouro':46, 'Prata':37, 'Bronze':38},
'China':{'Ouro':26, 'Prata':18, 'Bronze':26},
'Britain':{'Ouro':27, 'Prata':23, 'Bronze':17},
'Russe':{'Ouro':19, 'Prata':18, 'Bronze':19},
'Germany':{'Ouro':17, 'Prata':10, 'Bronze':15}
}

Converter Dicionário para DataFrame

Agora estamos usando a função from_dict do módulo DataFrame do Pandas. A razão disso é por termos dicionários aninhados, portanto a transformação para DataFrame é ligeiramente diferente para que não tenhamos problemas.

olimpiada = pd.DataFrame.from_dict(Quadro_Medalhas_Olimpiada); olimpiada
olimpiada

Muitos sistemas ERP e CRM geram dados em formatos JSON. Então isso pode ser útil para trazer os dados para o ambiente do Jupyter Notebook e depois começar o processo de análise.

Verificar tipo do Objeto

type(olimpiada)
pandas.core.frame.DataFrame

Por que verificar o objeto?

A importância de se verificar o tipo de objeto é porque tudo em Python é objeto. Cada objeto tem atributos e métodos específicos, variando de acordo com o seu tipo.

Criar Subset

Vamos fazer uma chamada ao DataFrame olimpíada e passar entre colchetes o nome de uma das colunas.

Ou seja, faremos um fatiamento do DataFrame buscando uma coluna pelo seu nome. Nada mais simples e útil do que isso.

MedalhasChina = olimpiada['China'] 
Medalhas_China
Bronze 26
Ouro 26
Prata 18
Name: China, dtype: int64

Acima trouxemos apenas os valores referentes ao país China e alocamos dentro do subset MedalhasChina.

Outra notação

Podemos também chamar a coluna com outro tipo de notação. Mencionamos o dataframe e colocamos um “ponto”. Ou seja, estamos chamando um atributo do DataFrame após o ponto, e este atributo é a sua coluna.

olimpiada.RusseBronze    19
Ouro 19
Prata 18
Name: Russe, dtype: int64

Filtro de Colunas

Podemos ainda realizar um filtro chamando múltiplas colunas. Para isso temos o par de colchetes exterior que denota o slicing e o par de colchetes interior que determina uma lista de strings que representam as colunas.

olimpiada[['Russe','Germany']]

Função .get

Podemos ainda utilizar a função .get(), nesse caso passamos entre parênteses, como parâmetro, a coluna que queremos retornar.

olimpiada.get('Germany')Bronze    15
Ouro 17
Prata 10
Name: Germany, dtype: int64

DataFrame Original

Para deixar claro que o DataFrame continua no formato original.

olimpiada
DataFrame olimpiada intacto
type(olimpiada)
Pandas.core.frame.DataFrame

Index Loc

Podemos utilizar o iloc — Index Loc, que é uma busca dentro do DataFrame utilizando a locacalização numérica de índice.

Abaixo indicamos que queremos a línha de índice 1, ou seja, a segunda linha dessa tabela.

olimpiada.iloc[1]USA        46
China 26
Britain 27
Russe 19
Germany 17
Name: Ouro, dtype: int64

Slicing

olimpiada # DataFrame original
olimpiada
olimpiada[:2] # Retornar tudo até a 3° linha (exclusiva)
olimpiada[:2]
olimpiada[2:] # Retornar tudo a partir da terceira linha
olimpiada[2:]
olimpiada[::2] # Dois pontos retornam tudo, saltando de 2 em 2.
olimpiada[::2]
olimpiada[::-1] # Retornar tudo em ordem inversa
olimpiada[::-1]
olimpiada # DataFrame Original
nada mudou

Slicing por indexação

Para isso chamaremos o atributo .loc e passamos como parâmetro o nome do índice. Por isso é vantajoso renomear os índices no DataFrames.

1. olimpiada.loc['Ouro'] 
USA 46
China 26
Britain 27
Russe 19
Germany 17
Name: Ouro, dtype: int64
2. olimpiada.loc[:,'USA']# Retornar todas as linhas para coluna USA
Bronze 38
Ouro 46
Prata 37
Name: USA, dtype: int64
3. olimpiada.loc['Prata','China'] # Mais de um elemento como
18

Esse tipo de tarefa de slicing feita acima, é sem dúvida, uma ajuda considerável e certeira para um cientista de dados durante a manipulação dos dados.

olimpiada.loc['Prata']['China'] #Outro notação com colchetes 
18

Podemos retornar mais uma vez, apenas 1 elemento do dataframe. Nesse caso, tudo que tenha índice igual a prata.

olimpiada.loc['Prata'] # Todos os países com índice Prata
USA 37
China 18
Britain 23
Russe 18
Germany 10

Name: Prata, dtype: int64

Retornar tudo com índice igual a ouro com medalhas acima de 20.

olimpiada.loc['Ouro'] > 20 # Combinação de índice com condição
USA True
China True
Britain True
Russe False
Germany False

Name: Ouro, dtype: bool

Complicando um pouco

Podemos mudar a notação. Indicamos todas as linhas, e indicando como coluna o próprio dataframe em Ouro, ou seja, estamos filtrando o próprio DataFrame com alguma condição de coluna.

olimpiada.loc[:, olimpiada.loc['Ouro'] > 20]

Conseguimos fazer filtros a um nível de detalhe muito grande.

olimpiada.loc[:, olimpiada.loc[‘Ouro’] > 20]
olimpiada.loc['Prata'] > 20 #Retorno lógico tipo booleano
USA True
China False
Britain True
Russe False
Germany False

Name: Prata, dtype: bool
olimpiada.iloc[:2] #Localização por índice mais veloz que LOC.
olimpiada.iloc[:2]
1. olimpiada.iloc[2,0:2] # Terceira linha e até a segunda coluna
USA 37
China 18

Name: Prata, dtype: int64
2. olimpiada.iloc[1,:]
USA 46
China 26
Britain 27
Russe 19
Germany 17

Name: Ouro, dtype: int64
3. olimpiada.iloc[2, 0]
37

Remover um membro do dataframe

Deletar coluna do nosso conjunto de dados:

del olimpiada['USA'] # Deletar tudo da coluna USA
olimpiada

Inserindo um membro no dataframe

Tamgém podemos inserir uma nova coluna. Chamamos a função insert e indicamos qual o índice que queremos inserir, o nome que queremos dar à coluna e os valores dessa nova coluna.

olimpiada.insert(0, 'Brasil', (7, 6, 6))
olimpiada
olimpiada.insert(0, ‘Brasil’, (7, 6, 6))

Resumo estatístico completo do dataframe

Por último, podemos chamar a função describe para resumir estatisticamente o nosso conjunto de dados. Portanto, com a função describe podemos fazer um resumo estatístico completo.

olimpiada.describe()

Como pudemos ver, a linguagem Python, para manipulação de dados, apresenta ferramentas extremamente poderosas.

Obrigado.

Composing a repository of books (i bought), authors (i follow) & blogs (direct ones) for my own understanding.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store