Autor: Felipe Maia Polo - Fundador e ex-presidente do Neuron - Data science and Artificial Intelligence, economista pela USP e mestrando em Estatística pela mesma instituição. Apaixonado por matemática, estatística e data science.
Contato: felipemaiapolo@gmail.com - https://www.linkedin.com/in/felipemaiapolo/
Feedback: https://forms.gle/U6yBVSYwxNRWaE15A
Sugestões de leitura
Python é uma versátil linguagem de programação e que, ultimamente, vem sendo muito usada no mercado para se fazer análise de dados, sobretudo fazer o uso de modelos estatísticos e de machine learning. Vou primeiramente apresentar algumas das principais funções da linguagem e depois introduzir os pacotes mais importantes para nós: Numpy e Pandas.
Variáveis são os espaços de memória criado pela linguagem para você manipular e armazenar dados. Para usar uma variável basta escolher uma letra ou palavra e atribuir um valor a ela com o sinal de "=". É importante dizer que há diferenciação entre letras maiúsculas e minúsculas, que não pode haver espaços na nomeação e que o primeiro caracter não pode ser um número. Existem basicamente três tipos de variáveis que são mais importantes para nós: as strings (guardam textos), integers (guardam números inteiros) e floats (guardam números racionais).
#Criando variável do tipo string
x="Data Science"
#Criando variável do tipo integer
y=42
#Criando variável do tipo float
z=3.1415
#Mostrando os valores e tipos das nossas variáveis
print(type(x),x)
print(type(y),y)
print(type(z),z)
O Python designa o tipo da variável automaticamente quando incluímos seus valores. É possível fazer a conversão de um tipo de variável para outro:
#Convertendo uma string em float
w="2.71"
w=float(w)
print(type(w),w)
#Convertendo uma integer em float
y=float(y)
print(type(y),y)
Para realizarmos as operações (matemáticas e testes lógicos) no Python usamos os operadores. Os operadores matemáticos nos permitem fazer somas, subtrações, divisões entre outras operações. Já os operadores lógicos realizam comparações e a resposta da linguagem será ou Verdadeiro (true) ou Falso (false).
#Realizando algumas operações matemáticas
x=3
y=8
z=-1
print(x-y) #Subtração
print(y*z+x) #Multiplicação e adição
print(y/x) #Divisão
print(y**z) #Potenciação
#Realizando alguns testes lógicos
print("3<4:",3<4)
print("3>4:",3>4)
print("1>=1:",1>=1)
print("9==9:",9==9)
print("x>(z+3)**2:",x>(z+3)**2)
#Podemos guardar o valor do teste dentro de uma variável
teste=3<4
print("\n")
print(type(teste),teste)
Listas são objetos capazes de armazenar outros objetos, sendo que uma lista pode conter qualquer coisa, inclusive outra lista. Cada valor da lista recebe um índice a partir do 0:
#Criando uma lista
lista = [2,'1',['big','data'],4,5.0]
print(type(lista))
print(len(lista)) #Tamanho da lista
print(lista)
#Acessando alguns dos objetos dentra da lista pelos índices
print("lista[0]: ",lista[0])
print("lista[-1]: ",lista[-1])
print("lista[1:4]: ",lista[1:4]) #perceba que quando utilizamos "x:y", o Python retorna os elementos de "x" a "y-1"
print("lista[4:]: ",lista[4:])
print("lista[:2]: ",lista[:2])
É possível adicionar ou remover objetos dentro de listas já existentes, além de ser possível concatenar duas listas:
#Criando lista vazia
lista2=[]
#Preenchendo a lista
lista2.append(6)
lista2.append("99")
lista2.append("Data Science")
lista2.append("99")
print(lista2)
#Checando se há um elemento específico dentro da lista
print("\n") #Pulando uma linha no output
print("99" in lista2)
#Excluindo um elemento específico
lista2.remove('99')
print("\n") #Pulando uma linha no output
print(lista2)
#Concatenando duas listas
lista.extend(lista2)
print("\n") #Pulando uma linha no output
print(lista)
Outro tipo de objeto semelhante às listas é o Dicionário. O dicionário armazena uma sequência de objetos os quais cada item é uma chave, que é associada a um valor:
#Criando um dicionário
dic={'carro': 'gol', 'comida': 'pizza',
'animal': 'abelha', 'matéria': 'matemática','número':70}
print(dic)
Podemos adicionar, alterar e acessar os objetos dentro dos dicionários por suas chaves:
#Acessando um objeto
print(dic["carro"])
#Alterando o objeto
dic["carro"]="corsa"
print(dic["carro"])
#Adicionando objeto
dic[99]=3.14
print(dic[99])
O dicionário é muito útil pois os índices são customizáveis, ao contrário das listas, e pode-se guardar qualquer tipo de objeto dentro, até mesmo bases de dados.
Os loops são estruturas usadas para repetir o mesmo bloco de comandos várias vezes. Estudaremos duas função de repetição do python o while(): e o for.
O for repete o bloco de comando até que um limite estabelecido seja atingido (e.g. "para i começando de 0 até i=4, faça alguma coisa"), a sintaxe é feita da seguinte forma:
#Exemplo For
for item in range(5):
print (item, item**2) #número e seu quadrado
É importante dizer que é possível iterar sobre objetos de uma lista:
#Criando um dicionário
dic={'carro': 'gol', 'comida': 'pizza',
'animal': 'abelha', 'matéria': 'matemática','número':70}
index=['carro','animal','matéria']
for i in index:
print(i,":",dic[i])
O loop While repete ações até que uma condição, inicialmente verdadeira, seja falsa:
#Exemplo While
i=0
while i<10:
i=i+1
print(i)
Um aspecto intrínseco à codificação é o processo decisório. No Python, este processo se dá por meio da avaliação de expressões booleanas (expressões cujo resultado ou é TRUE ou é FALSE). Ou seja, em determinada situação, se a expressão booleana der TRUE, o programa seguirá um caminho, caso dê false, seguirá outro. A estrutura decisória é apresentada da seguinte forma:
#Exemplo If
x=2
if x<3:
print(x**2)
else:
print(x)
No exemplo acima temos uma estrutura condicional muito simples com somente uma condição: Abaixo um exemplo mais complexo:
#Exemplo If
x=4
if x<3:
print(x**2)
elif x<5:
print(x**3)
else:
print(x)
Vamos agora utilizar mais de uma condição para nossos testes:
#Exemplo If
x=40
if x>3 and x<10: #As duas condições devem ser verdadeiras
print("Primeiro.")
elif x>50 or x<30: #Pelo menos uma das condições deve ser verdadeira
print("Segundo.")
else:
print("Terceiro.")
As funções em Python são caracterizadas pelo comando "def" seguido pelo nome da função e os argumentos que ela recebe, assim indicando o início de uma função:
def minha_funcao(.):
Chamamos de argumentos de uma função os elementos que serão manipuladas dentro de uma função, sendo esses elementos de qualquer tipo oferecido pela linguagem (listas, strings, etc). Para usarmos o resultado gerado por uma função usamos o comando "return" - ele permite fazer que esse resultado seja mandado para uma variável fora da função:
#Exemplo 1
def media(x1,x2):
return (x1+x2)/2
media(2,3)
#Exemplo 2 (equações de 2º grau)
def bhaskara(a,b,c):
delta=b**2-4*a*c
if delta<0:
return "A equação não tem raízes reais."
elif delta==0:
return -b/(2*a)
else:
return (-b-(delta)**.5)/(2*a), (-b+(delta)**.5)/(2*a)
#Resolvendo equações de 2º grau
print(bhaskara(1,1,1))
print(bhaskara(1,4,0))
print(bhaskara(2,0,0))
#Exemplo 3 (concatenando strings)
def concat(s1,s2,s3):
return s1+s2+s3
print(concat("Hello"," ","World!"))
Numpy é um biblioteca do Python que nos permite trabalhar com vetores, matrizes e tensores de forma geral (arrays) de forma mais eficiente que as ferramentas nativas da linguagem que usa listas.
#importando biblioteca
import numpy as np
Criando arrays usando a biblioteca Numpy:
#inicializando um array
#array unidimensional (vetor)
arrayU=np.array([1,2,3])
print("Array unidimensional(vetor): ")
print(arrayU,'\n')
#array bidimensional(matriz)
arrayB=np.array([[1,2,3],[4,5,6],[7,8,9]])
print("Array Bidimensional(matriz): ")
print(arrayB,'\n')
Podemos criar arrays apenas com zeros com o método np.zeros(). No argumento do método colocamos o formato que o array assumirá:
#podemos criar um array apenas com zeros
arrayZeros = np.zeros(3)
print("Array de zeros: ",arrayZeros)
#Automaticamente, a função faz com que os números sejam do tipo float
print(type(arrayZeros[0]))
#basta fazer o seguinte para mudar o tipo da variável
arrayZeros = np.zeros(3,dtype=int)
print("Array de zeros Inteiros: ",arrayZeros)
Podemos criar também arrays de números 1 com o método np.ones() e arrays vazios com o método np.empty():
#Array de 1s
arrayOne = np.ones([3,2])
print("array de 1: ")
print(arrayOne)
#Array vazio
arrayEmpty= np.empty(3) #inicializa com o endereço de memória da variável
print("array vazio: ")
print(arrayEmpty)
Podemos também modificar um array já criado mudando seu formato (shape) como for necessário. Usar método np.shape():
#criando um array normal
arrayShape = np.array([1,2,3,4])
print("Array com formato inicial: ",arrayShape)
print("Dimensões do array: ",arrayShape.shape)
Modificando as dimensões originais:
arrayShape.shape =(2,2)
print("Array modificado: ")
print(arrayShape)
print("Dimensões do array: ",arrayShape.shape)
É possível também realizar cortes de diversas maneiras no array unidimensional. Agora estudaremos como fazer isso:
#vamos criar array
arrayCortes = np.arange(1,10)
#podemos printar o array inteiro com [:]
print("Array inicial: ",arrayCortes[:])
#podemos printar o array ao contrário com [::-1]
print("Array ao contrário: ",arrayCortes[::-1])
#podemos cortar do meio pra frente
print("Array do meio pra frente: ",arrayCortes[5:])
O mesmo vale para matrizes:
#criando matriz bidimensional
arrayCortes.shape= (3,3)
print("Matriz inicial: ")
print(arrayCortes)
#podemos imprimir só uma coluna específica
print("\n","Matriz Coluna: ")
print(arrayCortes[:,1])
#ou uma linha específica
print("\n","Matriz Linha: ")
print(arrayCortes[1,:])
#até mesmo um pedaço da matriz
print("\n","Matriz pedaço: ")
print(arrayCortes[1:,1:])
Agora vamos ver alguns métodos matemáticos do Numpy:
#Criando array
A = np.array([1,0,3,6,2,1,7,5,2])
print("Array Inicial: ",A)
#Ordenando o array
A.sort()
print("\n","Array ordenado: ",A)
#Soma elementos do array
print("\n","Soma dos elementos: ",A.sum())
#Média dos elementos do array
print("\n","Média dos elementos: ",A.mean())
#Maior elemento
print("\n","Array maior elemento: ",A.max())
#Transposta de um matriz
A.shape =(3,3)
print("\n","Transposta: ")
print(A.T)
#Matriz Inversa
print("\n","Inversa: ")
print(np.linalg.inv(A))
Com matrizes (array bidimensional) é a mesma coisa, com exceção da multiplicação - a veremos agora. Primeiramente, lembremos que para multiplicar duas matrizes (A e B) o número de colunas da matriz A tem que ser iqual ao número de linhas da Coluna B:
Podemos realizar operações algébricas de maneira muito simples:
A = np.array([1,2,3,4])
B=np.array([5,6,7,8])
A.shape=(2,2)
B.shape=(2,2)
print("Matriz A: ")
print(A, "\n")
print("Matriz B: ")
print(B, "\n")
#Matriz A X B
print("Matriz A X B : ")
print(A @ B, "\n")
#Array X matriz
print("Array [2,3] x A : ")
print( [2,3] @ A)
Conheceremos agora uma das bibliotecas mais importantes e mais usadas para a manipulação e análises de dados no Python - o Pandas. O Pandas oferece diversas funções que facilitam a manipulação e visualização dos dados.
#Importando a biblioteca
import pandas as pd
Como dito anteriormente, o Pandas facilita a visualização de dados por causa da estrutura que ele é capaz de comportar as bases de dados - essa estrutura é chamada de DataFrame. Vamos criar um dicionário e depois transformá-lo em DataFrame para vermos sua estrutura:
dicionario = {"País": ["Brasil", "Rússia", "Índia", "China", "África do Sul"],
"Capital": ["Brasília", "Moscou", "Nova Deli", "Pequim", "Pretória"],
"Área": [8.516, 17.10, 3.286, 9.597, 1.221],
"População": [200.4, 143.5, 1252, 1357, 52.9]}
Brics = pd.DataFrame(dicionario)
print(Brics)
Podemos checar as variáveis contidas nesse com a função ".columns":
#Variáveis
Brics.columns
Podemos ver mais ou menos o que está contido no data set utilizando a função ".head()". Ela retorna as cinco primeiras linhas da base de dados:
Brics.head()
É possível também tirar algumas medidas descritivas das variáveis numéricas:
Brics.describe()