
Com o avanço de inúmeros sistemas para organizar nosso trabalho e vida pessoal como ERP, CRM e aplicativos, começamos a ter um número grande de dados estruturados.
Planilhas são um exemplo de estruturação de dados onde geramos colunas e linhas para poder organizá-los e permitir gerarmos novas inferências sobre eles.
Dentro do Python, o Pandas se destacou como biblioteca para processar dados estruturados.
Para instalar o pandas, usamos o seguinte comando:
pip install pandas (No colab usa-se o ! para comandos que seriam aplicados fora do python, nesse caso seria !pip install)
Já dentro do python, para importação da biblioteca pandas, usamos o seguinte comando:
import pandas as pd
As series são arrays unidimensionais que apresentam uma indexação (numérica ou de rótulos) marcando a posição de cada elemento. Vejamos como podemos criar esse objeto e observá-lo:
Ex.:
serie_1 = pd.Series(data=[10,22,23,48,54], index=[0,1,2,3,4])
Os índices são valores que preferencialmente devem ser únicos e que são usados para garantir a unicidade dos dados e facilitar a localização e manipulação dos registros.
Para representar dados de duas dimensões temos o dataframe. Ele é um conjunto de series, formando assim linhas e colunas.
Ex.:
dados = {'prova_1': [6,7,8,8,9,3,6],
'prova_2': [7,8,5,7,10,8,7],
'nome': ['Ana', 'Pedro', 'João', 'Carla', 'Silvio','Teresa', 'Claudia'],
'turma':['A','A','B','B','A','B','B']}
df = pd.DataFrame(data=dados)
O pandas disponibiliza o comando “append” que insere um registro no final do dataframe.
Ex.:
df = df.append({'prova_1': 6, 'prova_2': 7, 'nome': 'Cristiane', 'turma': 'A'},ignore_index=True)
O parâmetro “ignore_index” é necessário para indicarmos que no nosso caso o índice não será passado.
O comando shape retorna o número de linhas e colunas que apresenta nossa serie ou dataframe.
Ex.:
df.shape
O comando columns contém as colunas do nosso dataframe.
Ex.:
df.columns
Podemos mudar o nome das nossas colunas atribuindo novos nomes:
Ex.:
df.columns = ['Prova um', 'Prova dois','Nomes', 'Turma']
Para visualizar os índices do nosso dataframe usamos o atributo index:
Ex.:
df.index
Para modificar o index do nosso dataframe como no exemplo:
df = df.set_index(keys = 'nome')
Os tipos de dados principais do pandas são:
float64 - números com casas decimais
int64 - números inteiros
string - conteúdos textuais
object - conteúdos indefinidos
datetime64 - data e hora
bool - valores booleanos (true ou false)
Para conhecer os tipos de dados das colunas do dataframe, podemos utilizar o atributo dtype:
Ex.:
df.dtypes
No caso específico de dataframe podemos usar também o método info:
Ex.:
df.info()
Para visualizar as primeiras n linhas do conjunto de dados no pandas podemos usar o método head.
Ex.:
df.head(n=3)
Para visualizar as últimas n linhas usamos o comando tail:
Ex.:
df.tail(n=3)
Podemos selecionar somente uma coluna de informações, por exemplo.
df[‘Prova um’]
Para sabermos um único valor podemos passar a coluna e depois o index da linha que queremos visualizar.
Ex.:
df[‘Prova um’][‘Ana’]
Podemos da mesma forma, atribuir um novo valor para ela:
Ex.:
df[‘Prova um’][‘Ana’] = 8
Mas para alterar os dados, o pandas sugere usarmos o método loc. Ex.:
df.loc['Silvio','Prova um'] = 10
No método loc, podemos indicar n índices. Ex.:
df.loc[['Carla','Silvio', 'Teresa'], 'Prova um']
Ou usar os dois pontos para indicar que queremos os registros de determinado intervalo de índices. Ex.:
df.loc['Carla':'Teresa', 'Prova um']
Já o comando iloc funciona de forma semelhante, porém indicamos para ele as posições dos dados no dataframe. Ex.:
df.iloc[4,0]
Podemos realizar filtros no nosso dataframe. Os operadores lógicos são:
== Igual
> Maior
>= Maior igual
<=Menor igual
!= Diferente
Podemos usar eles dentro do loc:
Ex.:
filtro = (df['Turma'] == 'A')
df[filtro]
Uma filtragem nada mais é do que uma seleção de informações que se enquadrem dentro de requisitos que determinamos.
Às vezes, precisamos usar filtros mais complexos com operadores lógicos como “and” e “or”.
O “and” que no pandas é representado por “&”. Fica assim:
filtro = ((df['Turma'] == 'A') & (df['Prova um']>7))
Da mesma forma, podemos usar o “ou” que no pandas é representado pelo sinal “|”. Ex.:
filtro = ((df['Prova dois']>=8) | (df['Prova um']>=8))
Outra forma de executar o mesmo código, mas digitando menos, é jogá-lo diretamente dentro da verificação do dataframe. Veja esse exemplo:
print(df[(df['Prova dois']>=8) | (df['Prova um']>=8) ])
Podemos incluir um novo registro também através do método loc, passando a sequência de valores que queremos incluir e especificando o index. Como o índice passado não existe, ele inclui um novo. Ex.:
df.loc['Marcelo'] = [10,4,'B']
Porém, se fazemos o mesmo comando, já tendo um índice com esse valor, ele entende que queremos atualizar os valores desse registro.
Caso precisemos atualizar o índice do nosso dataframe, podemos usar o seguinte comando. Ex.:
df = df.reset_index()
Com isso, nosso dataframe assume um índice numérico iniciando em 0.
Para conhecer a quantidade de valores vazios do nosso dataframe, usamos o comando isnull que retorna verdadeiro ou falso para cada registro.
Ex.:
df.isnull()
Após isso, para sabermos a quantidade usamos o sum().
Ex.:
df.isnull().sum()
Para preenchermos esses valores vazios, podemos usar o comando abaixo.
Ex.:
df = df.fillna(value=0)
Para preencher com valores somente em determinada coluna podemos usar o comando:
Ex.:
df = df.fillna(value={'Média':1})
Já um método que permite apagarmos os registros com valores nulos é o dropna.
Ex.:
df = df.dropna(axis=0)
Para sabermos todos os valores dentro do domínio de uma coluna, usamos o unique.
Ex.:
df['Nomes'].unique()
E para saber quantas vezes os valores aparecem em uma coluna, usamos o value_counts.
Ex.:
df['Nomes'].value_counts()
Podemos realizar várias operações estatísticas no nosso dataframe.
Uma opção é usar o método describe que traz um resumo estatístico.
Ex.:
df.describe()
Ou usar os métodos individuais:
O método sum() realiza a soma dos valores da nossa coluna.
Ex.:
df['Prova um'].sum()
O método max() traz o maior valor da nossa coluna.
Ex.:
df['Prova um'].max()
O método min() traz o menor valor da nossa coluna.
Ex.:
df['Prova um'].min()
O método mean() retorna a média da nossa coluna.
Ex.:
df['Prova um'].mean()
O método median() retorna a mediana da nossa coluna.
Ex.:
df['Prova um'].median()
O Pandas oferece um método capaz de reestruturar nossas informações a partir de uma ou mais colunas. Para isso usamos o groupby. Após ele, podemos usar funções estatísticas para serem aplicadas nos agrupamentos.
Ex.:
df.groupby(by=['Turma']).mean()
Para ordenar podemos usar o sort:
Ex.:
df.groupby(by=['Turma'])['Prova um'].mean().sort_values(ascending=True)
Uma forma de apresentar as informações obtidas é de forma visual, criando gráficos.
O Pandas simplifica muito nossa vida, com o comando plot. Vejamos:
df.groupby(by=['Turma'])['Prova um'].mean().sort_values(ascending=True).plot(kind='bar')
O Pandas permite diferentes tipos de gráficos, como de barras, pizza, de linha e histograma.
df['Turma'].value_counts().plot(kind='pie')
A biblioteca Pandas apresenta vários métodos para salvar arquivos:
df.to_csv(‘meu_arquivo.csv’, index= False)
O parâmetro denominado index, dentro do método, indica que não queremos que a indexação seja salva como uma coluna no arquivo resultante.
Para salvar em um arquivo do excel, podemos usar o comando:
df.to_excel(‘meu_arquivo.xlsx’)
O Pandas oferece métodos para importar arquivos.
Ex.:
df = pd.read_csv('meu_arquivo.csv')
Podemos também abrir arquivos a partir de urls. Além disso, especificar o limitador do csv com o comando abaixo:
df = pd.read_csv('https://raw.githubusercontent.com/brunamulinari/BasicPythonProjects/main/Base_ficticia/baseficticia.csv', delimiter=';')
Temos um grande volume de dados a nossa volta, mas para prepará-os para análises mais profundas, muitas vezes, precisamos fazer o chamado ETL (Extração, Tratamento e Limpeza).
Muitas vezes os dados estão no formato csv. Ele nada mais é do que um formato de comunicação de dados que usa “,” para delimitar os campos. Ex.:
nome,cpf,valor
Fernando Cesar,00000000000,R$ 45
Maria Clara,11111111111,R$ 98
Paulo Roberto,33333333333,R$ 92
Podemos realizar a extração dos dados carregando ele no python em um objeto DataFrame (pacote pandas) para que possamos aplicar os métodos de tratamento, limpeza e transformação.
Usamos a função pd.read_csv() para ler um csv e retornar em um dataframe.
Mas existem casos de variações de csv. Um deles é que o padrão utilizado pode ser com delimitadores diferentes de vírgula, como caracteres especiais.
Para isso podemos usar o parâmetro sep no read_csv, repassando o delimitador correto. Ex.:
df = pd.read_csv(arquivo, sep = "\t")
Para analisar os campos de um dataframe podemos usar o comando df.dtypes.
Podemos criar colunas novas no nosso dataframe, para isso, basta atribuir ao dataframe uma coluna nova e informar o seu valor, ex:
df['valordesconto'] = df['venda'] * df['porcdesconto']
Nesse exemplo, a coluna valordesconto não existia. Ela foi criada com base nos valores das duas outras colunas.
Para trazer sempre valores absolutos, ignorando o sinal de negativo, podemos usar a função abs().
Para deletar colunas podemos usar a função drop. Ex.:
dfPromocao .drop("Year_Birth", axis = 1, inplace = True)
Um padrão interessante é de não ter espaço no nome da coluna. Com isso, você pode referenciar um conjunto de colunas do dataframe, omitindo o uso das aspas duplas com colchetes caso este nome não tenha nenhum espaço entre seus caracteres.
Ao invés de usar df[“Cliente ID”], podemos usar o comando dessa forma df.Year_Birth.
Podemos renomear as colunas com o seguinte comando:
df = df.rename(columns={"Client ID": "CLIENT_ID"})
Podemos criar uma função para cuidar desse tratamento e de outros que acharmos interessante. Ex.:
def tratar_nomes(x):
x = x.replace(" ", "_").upper()
return x
Para utilizá-la em todas as colunas do dataframe, basta executar o método "built-in" da linguagem python, o map(). Ex.:
cols = list(df.columns)
cols_tratadas = map(tratar_nomes, cols)
df.columns = list(cols_tratadas)
A função value_counts() imprime os valores existentes nesta feature em conjunto com o volume de registros.
Para classificar valores de uma coluna, podemos criar um dicionário realizando a conversão. Ex.:
ensino_dict = {
"Graduation": "MID",
"PhD": "HIGH",
"Master": "HIGH",
"2n Cycle": "LOW",
"Basic": "MID"
}
Para modificar o valor de cada registro, podemos usar o método apply que varre linha a linha do dataframe, atribuindo cada valor na variável de lambda, no caso o x. Ex.:
df["Education"].apply(lambda x: ensino_dict[x])
Aqui, estamos passando o valor como chave no dicionário, assim ele retorna o conteúdo referente aquela chave.
Podemos usar também funções dentro do apply ou se referenciando a funções externas. Veja um exemplo:
tmp["child_flag"] = tmp.apply( lambda x: 1 if x.Kidhome + x.Teenhome > 0 else 0, axis = 1)
print(tmp["child_flag"])
Podemos rapidamente mapear o volume de valores NaN (Not a Number) chamando a função isna():
df.isna().sum()
Podemos remover os registros com valor NaN através do comando:
tmp = df["Income"].dropna()
Outro recurso utilizado é de preencher os valores nulos com a média dos registros:
df["Income"] = df["Income"].fillna(df["Income"].mean())
As APIs (interface de programação de aplicações) surgiram para facilitar esse trabalho e acabam fornecendo entradas e saídas de dados do sistema que podem ser acessados por código de programação.
São uma excelente forma de compartilhar dados. Quando comparado com outras formas de integração como csv, ou processos manuais, ela possui grandes vantagens como velocidade, facilidade, segurança e integridade dos dados.
As APIs são disponibilizadas pelos sistemas com os quais queremos conectar como erps, crms entre outros. Caso o sistema com o qual você queira se conectar tenha uma api, consulte sua documentação, que geralmente é disponibilizada em conjunto.
Na maioria esmagadora das vezes, os objetos de retorno das apis estarão formatados em "application/json", que pode ser facilmente transformado em um objeto dict() - já conhecido por muitos de vocês. Assim podemos realizar a manipulação dos mesmos convertendo os dados por exemplo para um dataframe do pandas.
O primeiro passo que precisamos para acessar uma api através do python é gerar o endereço completo de acesso.
Através da documentação disponibilizada, conseguimos identificar a URL que preciso requisitar para acessar tal função.
Aqui estamos acessando a API da Exchange que fornece as cotações de criptomoedas.
https://api.binance.com/api/v3/klines?symbol=BTCUSDT&interval=1h&startTime=1634243893
No caso dela, precisamos montar o endereço considerando a seguinte estrutura:
1. Base = https://api.binance.com
2. Rota = /api/v3/klines
3. Parâmetros = ?
Vamos nesse primeiro momento focar nos parâmetros.
Podemos montar a url usando o format e preenchendo com as variáveis que precisamos especificar, conforme a documentação. Nesse exemplo:
QUERY_PARAMS = "?symbol={}&interval={}&startTime={}".format(symbol, interval, startTime)
O código completo para montar o parâmetro ficaria assim:
from datetime import datetime, timedelta
startTime = datetime.now()
startTime = datetime.now() - timedelta(5)
startTime = int(startTime.strftime("%s"))
QUERY_PARAMS = "?symbol={}&interval={}&startTime={}000".format(symbol, interval, startTime)
print(QUERY_PARAMS)
Depois de criar os parâmetros da nossa api, podemos construir a url completa para acessar. Veja o exemplo:
URL_PRECOS_BITCOIN = API_URL + API_ROUTE + QUERY_PARAMS
print("\nURL da requisicao: {}".format(URL_PRECOS_BITCOIN))
O resultado é:
https://api.binance.com/api/v3/klines?symbol=BTCUSDT&interval=1h&startTime=1634243893
Para fazer a requisição dentro do python, usaremos a biblioteca requests. Podemos fazer uma requisição com o código abaixo:
import requests as r
response = r.get(url = URL_PRECOS_BITCOIN)
print(response.json()[0])
[RESULTADO]
[1502942400000,
'4261.48000000',
'4313.62000000',
'4261.32000000',
'4308.83000000',
'47.18100900',
1502945999999,
'202366.13839304',
171,
'35.16050300',
'150952.47794304',
'7887.63551305']
A resposta da API também carregara em si um corpo (body) com o conteúdo solicitado e um status (http_code) que indicará valores no range entre 200 e 300, em casos de uma resposta positiva - sendo o 200 = successful.
Podemos transformar o resultado através do comando: response.json()
Muitas vezes precisaremos tratar o resultado da API para conseguir gerar um dataframe.
Uma das formas é salvando em um arquivo csv que pode ser visualizado posteriormente em aplicativos como o Google Sheets ou no excel.Ex:
df.to_csv("/caminho_diretorio/nome_arquivo.csv")
Outra grande fonte de dados que acaba sendo utilizada pelos analistas de dados são os chamados banco de dados.
Vamos utilizar o próprio pandas para manipular nossas ações no banco de dados. Para isso, precisamos ter em mãos credenciais de acesso da nossa base.
As credenciais exigem as seguintes informações:
1. Nome usuario
2. Senha usuario
3. Nome do host
4. Port de entrada
5. Nome do banco de dados
Crie depois uma string de conexão. Ex.:
STRING_DE_CONEXAO = "mysql+pymysql://{}:{}@{}:{}/{}".format(
credenciais["username"], credenciais["password"],
credenciais["hostname"], credenciais["port"], credenciais["database"]
)
Agora que temos nossa string de conexão configurada, podemos acessar nossa base de dados.
A leitura de dados acaba sendo realizada através da função read_sql chamada a partir do nosso dataframe.
QUERY = """"""
SELECT
TIME,
OPEN
FROM preco_criptomoedas
WHERE OPEN > 54657
""""""
output = pd.read_sql(QUERY, conn_obj)
conn_obj.close()
output.head(5)
Aprenda a manipular dados com python com essa fantástica biblioteca. Nesse curso, você irá acompanhar o passo a passo para um processo completo de análise de dados usando o Pandas.
Todos os vídeos são roteirizados onde cada aula possui exercício prático e resposta, também em vídeo. As aulas são criadas com base na metodologia da escola Harve, que hoje é referência na formação de profissionais para a área de tecnologia.
Nesse curso, você irá navegar pelos seguintes tópicos:
Importar biblioteca e carregar arquivos csv.
Analisar informações da estrutura de dados gerada.
Analisar informações do conteúdo utilizando funções de estatística.
Manipular adição, atualização e exclusão de dados dos conjuntos de dados.
Realizar filtros com comandos fáceis através do loc e do iloc.
Gerar gráficos a partir do próprio conjunto de dados.
Salvar arquivos após a manipulação dos dados.
Criar colunas a partir de outras colunas.
Acessar apis e carregar os dados em um dataframe.
Acessar banco de dados e carregar os dados em um dataframe.
Tratar dados usando comandos complexos como apply.
Montar strings de conexão para apis e banco de dados.
Com esse curso você será capaz de carregar dados de diversas fontes diferentes, tratar e disponibilizar em vários formatos. O que está esperando? Vamos começar.