Python para Ciência de Dados: Exploração e Visualização de Dados

Gilberto Pereira Sassi
Carolina Costa Mota Paraíba

Instituto de Matemática e Estatística - IME

Preparando o ambiente

Durante o curso

Usaremos nas aulas: colab.research.google.com.

Recomendamos instalar e usar Python com a versão pelo menos 3.10. + conda: anaconda.com/download


Na sua casa

A linguagem python

Sobre a linguagem python

  • linguagem interpretadada
  • lançada em 1991 por Guido von Rossum (pesquisador Centrum Wiskunde & Informatica (Instituto de Pesquisa Nacional para Matemática e Ciência da Computação))
  • propõe um sintaxe simples e clara usando indentação (espaço em branco) para organização
  • paradigmas: funcional e programação orientada a objetos
  • nome inspirado no grupo humorístico britânico Monty Python
  • linguagem de programação mais popular do planeta segundo IEEE

Motivos para adoção de python

  • Constante melhoramento e atualização.
  • Portabilidade (executável em praticamente todos os sistemas operacionais).
  • Grande comunidade de usuários e desenvolvedores.
  • Gráficos de maneira relativamente simples.
  • Interatividade.
  • Um grande comunidade de usuários (especialmente útil para resolução de problemas).

Onde estudar sozinho?

Tutoriais on-line

Livros

No youtube

Plataformas de ensino on-line

O Google Colab

  1. Crie uma pasta para o seu projeto em seu Google Drive.
  2. Crie as seguintes pastas dentro da pasta do projeto:
    1. dados
      1. brutos
      2. processados
    2. documentos
    3. codigos
    4. figuras
    5. tabelas
    6. legado
    7. notas
    8. relatorio

Crie um arquivo google colab como ilustrado na Figura 1.

Figura 1: Criando arquivo google colab.

Monte google drive como ilustrado na Figura 2.

Figura 2: Montando o google drive.

Usando Google Colab

  • Google Colab é um notebook (IDE Jupyter Notebook).
  • notebook é dividida em células.
  • Cada célula pode ser texto (markdown) ou código python.
  • Alguns atalhos úteis:
    • Ctrl+M depois B cria uma célula de código abaixo.
    • Ctrl+M depois A cria uma célula de código acima.
    • Shift+Enter: executa célula ativa e cria uma nova célula abaixo.
    • Ctrl+Enter: executa célula ativa.

E se der ruim?

Peça ajudar no ipython

?sum
help(sum)
Help on built-in function sum in module builtins:

sum(iterable, /, start=0)
    Return the sum of a 'start' value (default: 0) plus an iterable of numbers
    
    When the iterable is empty, return the start value.
    This function is intended specifically for use with numeric values and may
    reject non-numeric types.

Outras opções

Operações básicas

Soma

1 + 1
2

Substração

1 - 2
-1

Multiplicação

2 * 3
6

Divisão

1 / 3
0.3333333333333333

Potenciação

2**3
8

Resto da divisão

3 % 2
1

Divisão inteiro (quociente da divisão)

3 // 2
1

Operações básicas
Exercício

Qual o resultado das seguintes operações?

  1. \(5,32 + 7,99\)
  2. \(5,55 - 10\)
  3. \(3,33 \cdot 5,12\)
  4. \(1 / 4,55\)
  5. \(5ˆ{1,23}\)

Comparadores e operadores lógicos

Valores lógicos em python: True e False.

Comparadores lógicos.
Operador Descrição
< menor
> maior
<= menor ou igual que
>= maior ou igual que
== igual
!= diferente
Operadores lógicos - permite concatenar resultados lógicos.
Operador Descrição
and e
or ou
not negação

Comparadores e operadores lógicos
Exemplo

and

nome = "gilberto"
idade = 39
nome == "gilberto" and idade > 30
True

or

nome == "gilberto" or idade > 40
True

not

not (nome == "gilberto" or idade > 40)
False

Pacotes em python

instalação

!pip install scipy 
!conda install scipy

carregamento

import scipy

carregamento com rótulo

import pandas as pd

carregamento de apenas parte do pacote (chamado de módulo)

import scipy.stats as stats

Funções

Função é uma ação e tem os seguinte componentes na ordem:

  • nome da função
  • parênteses
  • argumentos posicionais
  • argumentos nomeados

\[ \overbrace{nome\_funcao}^{\text{nome da função}} \overbrace{(}^{\text{parênteses}} \overbrace{\texttt{valor1},\quad \texttt{valor2}}^{\text{argumentos posicionais}},\quad \overbrace{\texttt{nome1 = valor3},\quad \texttt{nome2 = valor4}}^{\text{argumentos nomeados}} \overbrace{)}^{\text{parênteses}} \]

exemplo

round(1.431144, ndigits=2)
1.43

Como criar funções

  • O espaço em branco é crucial na liguagem python.
  • O espaço determina onde e termina um bloco de código.
  • python não usa {} ou comandos begin/end.
def nome_funcao(valor1, valor2, nome1 = valor3, nome2 = valor4):
    linha1
    linha2
    linha3
    return valor

exemplo

def media_5(v1, v2, v3, v4, v5, tam = 5):
  resultado = (v1 + v2 + v3 + v4 + v5) / tam
  return resultado

print(media_5(1, 2, 1, 2, 0))
print(media_5(1, 2, 1, 2, 0, tam = 6))
1.2
1.0

Objetos em python

Objeto é uma unidade que combina dados, chamados de atributos, e comportamentos, chamados de métodos.

  • atributos: informações associadas ao objeto
    • .atributo (sem parênteses)
  • métodos: funções que podem usar atributos
    • .metodo(arg1, nome1 = valor) (com parênteses e argumentos)

tudo na linguagem python é um objeto.

dir(objeto) mostra todos atributos e métodos do objeto.

exemplo

nome = "gilberto"
nome.upper()
'GILBERTO'

Objetos em python

  • Capitalize a primeira letra de palavra na frase: “nasci, cresci e moro no brasil.”. Use o método title.
  • Arredonde o número \(10000,5643\) para uma casa decimal usando a função round.
  • Crie que calcule a média de 3 valores.

Estrutura de dados

Os dados em python

built-in - já vem instalado

  • valores escalares: números e strings - None, str, float, int e bool.
  • estrutura de dados: list, tuple, set e dict.

Pacote numpy

array (vetores e matrizes para matemática computacional);

Pacote pandas

Series (equivalente a vetor em R) e DataFrame (equivalente a data.frame em R).

Valores escalares

Valores escalares

Valores escalares built-in em python.
Tipo Descrição
None valor null (ausência de informação)
str texto
float número real
int número inteiro
bool Valor lógico: True e False
  • Usamos a função type para terminar o tipo de um objeto.
  • Podemos usar str, float, int e bool para mudar o tipo de um objeto.
    • bool(objeto) será False, se objeto for None, "" or 0.
  • strings pode ser encapsulado por: ', " e """.
    • """ permite que diversas linhas.

Valores escales
Exemplo

Número real

salario = 1518.55
type(salario)
float
# não é número real
salario = "1518.55"
type(salario)
str

Podemos converter um texto com número real para número real.

float(salario)
1518.55

Podemos converter número real para um texto com número real.

salario = str(1518.55)
type(salario)
str

Valores escales
Exemplo

Número inteiro

idade = 39
type(idade)
int
# não é número real
idade = "39"
type(idade)
str

Podemos converter um texto com número inteiro para número inteiro.

int(idade)
39

Podemos converter número inteiro para um texto com número inteiro.

idade = str(39)
type(idade)
str

Valores escales
Exemplo

Valor lógico

logico = True
type(logico)
bool
# não é número real
logico = "True"
type(logico)
str

Podemos converter um texto com valor lógico para valor lógico.

bool(logico)
True

Podemos converter valor lógico para um texto com valor lógico.

logico = str(False)
type(logico)
str

Valores escalares
Exercício

  • Crie três objetos chamados salario, idade e nome com seu salario, idade e nome de tipo float, int e str, respectivamente.
  • Crie uma função que calcule o aumento do seu salário com argumentos: salario e aumento em porcentagem. Lembre que o aumento é calculado por salario * (1 + aumento / 100).

f-string e soma de strings

f-string

Permite incluir objetos dentro de texto de uma forma simples.

f"texto {variavel1} texto texto {variavel2} texto {variavel3}."

Exemplo

nome = "Gilberto"
idade = 39
print(f"Meu nome é {nome} e tenho {idade} anos.")
Meu nome é Gilberto e tenho 39 anos.

soma de strings

+ concatena strings.

Exemplo

parte1 = "Meu nome é Gilberto"
parte2 = "tenho 39 anos."
print(parte1 + " e " + parte2)
Meu nome é Gilberto e tenho 39 anos.

Controle de fluxo

if, if-elif-else

Checa se declaração é verdadeira (True).

if

x = -10
if x < 0:
  print(f"{x} é um valor negativo.")
-10 é um valor negativo.

if-else

x = 0
if x < 0:
  print(f"{x} é um valor negativo.")
else:
  print(f"{x} é um valor não negativo.")
0 é um valor não negativo.

if-elif-else

x = 0
if x < 0:
  print(f"{x} é um valor negativo.")
elif x == 0:
  print(f"{x} é zero.")
else:
  print(f"{x} é um valor positivo.")
0 é zero.

Laço de repetição

for, while, pass, break, continue e range

  • range(inicio, fim, passo): produz uma coleção de valores inteiros incluindo inicio, excluindo fim e incremento passo.
  • for: permite percorrer uma coleção e realizar um cálculo para cada item da coleção.
  • while: realiza uma tarefa enquando uma declaração continuar verdadeiro.
  • pass: faça nada para permitir for e while vazios.
  • break: interrompe for e while.
  • continue: passe imediatamente para o próximo item da coleção.

for, while, pass, break, continue e range
Exemplo

for i in range(1, 50, 5):
  print(i**2 + 1)
2
37
122
257
442
677
962
1297
1682
2117

Pulando os valores pares.

for i in range(1, 11, 1):
  if i % 2 == 0:
    continue
  print(i)
1
3
5
7
9
nome = 39
while type(nome) != str:
  print(nome)
  nome = "gilberto"
39
x = 256
total = 0
while x > 0:
  if total > 500:
    print("passamos de 500")
    break
  total += x
  x /= 2
print(total)
passamos de 500
504.0

Laço de repetição for vazio.

for i in range(1, 20, 4):
  pass

for, while, pass, break, continue e range
Exercício

  • Resolve e imprima a equação i**3 % 2 para i indo de 1 até 20 de um 1 em 1. Use for.
  • Imprima apenas os valores ímpares entre 1 e 20. Use while.

Estrutura de dados built-in

Lista

  • Sequência de objetos (que não precisa ser escalar) armazenados em sequência na memória.
  • Objetos individuais podem ser atualizados e usamos [] para criar uma lista
equipe = ['Carolina', 'Gilberto', 'Ana Carolina', 'Miguel', 'Fernanda', 'Keila', 'Mayara']
print(equipe)
['Carolina', 'Gilberto', 'Ana Carolina', 'Miguel', 'Fernanda', 'Keila', 'Mayara']

Slicing

Criando uma sublista: [inicio:fim:passo]. A contagem começa em 0 na linguagem python.

  • Podemos omitir inicio e fim, se forem o primeiro e o último objeto da lista.
  • Caso passo seja 1, podemos omitir passo.
  • Um objeto da lista pode ser uma lista.
print(equipe[:2]) # dois primeiros elementos
print(equipe[2:]) # todos elementos a partir do terceiro elemento
print(equipe[2:4]) # segundo e terceiro elemento
['Carolina', 'Gilberto']
['Ana Carolina', 'Miguel', 'Fernanda', 'Keila', 'Mayara']
['Ana Carolina', 'Miguel']

Lista - métodos

Métodos para objetos do tipo list.
Método Descrição
append(elemento) Adiciona um objeto ao final da lista.
clear() Remove todos os objetos da lista.
copy() Cria uma cópia da lista.
count(elemento) Retorne a frequência de um objeto da lista.
extend(lista) Inclui uma lista ao final de outra lista.
index(elemento) Retorne a posição da primeira ocorrência de um objeto.
insert(posicao,elemento) Insire um objeto em uma posição.
pop() Remove o último elemento da lista.
remove(elemento) Remove a primeira ocorrência de um objeto.
reverse() Inverte a apresentação dos objetos.
sort(reverse=True|False) Ordena os objetos de uma lista. Se reverse=True, os objetos são ordenados em ordem descrescente.

Lista - métodos

equipe_copia = equipe.copy()
equipe_copia.append("Fulano")
print(equipe_copia)
['Carolina', 'Gilberto', 'Ana Carolina', 'Miguel', 'Fernanda', 'Keila', 'Mayara', 'Fulano']
equipe_copia.pop()
print(equipe_copia)
['Carolina', 'Gilberto', 'Ana Carolina', 'Miguel', 'Fernanda', 'Keila', 'Mayara']
equipe_copia.sort(reverse=True)
print(equipe_copia)
['Miguel', 'Mayara', 'Keila', 'Gilberto', 'Fernanda', 'Carolina', 'Ana Carolina']
pos = equipe_copia.index("Carolina")
pos
5
equipe_copia[pos] = 'Profa. Carolina'
print(equipe_copia)
['Miguel', 'Mayara', 'Keila', 'Gilberto', 'Fernanda', 'Profa. Carolina', 'Ana Carolina']

Lista - Métodos
Exercício

  1. Crie um lista com os nomes dos seguinte autores: Karl Marx, Engels, Lênin, Fidel Castro, Che Guevara.
  2. Ordene os nomes em ordem descrecente.
  3. Determine a posição de Fidel Castro na lista.
  4. Inclua Mao Zedong na lista.
  5. Substitua Fidel Castro por Ho Chi Min.

tupla

  • Semelhante a lista, mas não permite atualização de objetos da lista.
  • Usamos () para criar tuplas.
coordenacao = ('Carolina', 'Gilberto')
print(coordenacao)
('Carolina', 'Gilberto')
  • Podemos converter lista para tupla usando tuple.
  • Podemos convert tuple para lista usando list.
Métodos para objetos do tipo tuple.
Método Descrição
count(elemento) Retorne a frequência de um elemento da lista.
index(elemento) Retorne a posição da primeira ocorrência de um elemento.

tupla
Exemplo

participantes = ('Josefina', 'José', 'Josué', 'Josuel', 'Joelson', 'Jorel', 'Joaquina', 'José')
print(participantes)
('Josefina', 'José', 'Josué', 'Josuel', 'Joelson', 'Jorel', 'Joaquina', 'José')
participantes.count('José')
2
participantes.index('Jorel')
5

tuple
Exercício

  • Crie uma tupla com os nomes das participantes do curso de extensão Python para Ciência de Dados: Julia, Juliana, Jessica, Jennifer, Julia, Juliana , Joana, Joyce, Jessica e Jennifer.
  • Conte quantas Julia tem no curso.

set

  • Coleção de objetos sem ordem e sem repetição de elementos.
  • Usamos {} para criar um set.
  • Podemos usar a função set para convert listas e tuplas para set.
  • Permite realizar operações semelhantes a teoria de conjuntos.
nomes = {'José', 'José', 'Josué', 'Josué', 'Josefina', 'Josefina', 'Joaquina', 'Joaquina'}
print(nomes)
{'José', 'Josué', 'Joaquina', 'Josefina'}

set - métodos

Métodos para set.
Método Atalho Descrição
add() Adiciona um novo objeto a um conjunto
clear() Remove todos os objetos de um conjunto
copy() Cria uma cópia de um conjunto
difference() - Equivalente a \(A-B\) em teoria de conjuntos
difference_update() -= Realiza a operação \(A-B\), e atribui o resultado em \(A\)
discard() Remove um objeto específico de um conjunto
intersection() & Equivalente a \(A\cap B\) em teoria de conjuntos
intersection_update() &= Equivalente a \(A\cap B\) em teoria de conjuntos, e atribui o resultado em \(A\)
isdisjoint() Retorna True se os set não têm intersecção
issubset() <= Retorna True se \(A\subseteq B\)
< Retorna True se \(A\subset B\)
Métodos para set (continuação).
Método Atalho Descrição
issuperset() >= Retorna True se \(A\supseteq B\)
> Retorna True se \(A\supset B\)
pop() Remove o primeiro objeto listado na impressão de um conjunto
remove() Remove um objeto específico de um conjunto
symmetric_difference() ^ Equivalente a \(A\Delta B\) (diferença simétrica)
symmetric_difference_update() ^= Salva o resultado de \(A\Delta B\) em \(A\)
union() | Equivalente a \(A\cup B\)
update() |= Salva o resultado de \(A\cup B\) em \(A\)

set - métodos

Considere estudantes de duas turmas: economia e portugues.

economia = {"Ana", "Bruno", "Carlos", "Diana", "Eduardo", "Fernanda", "Gabriel", "Helena", "Igor", "Juliana"}
portugues = {"Carlos", "Diana", "Lucas", "Mariana", "Natália", "Otávio", "Paula", "Rafael", "Sofia", "Gabriel"}

print(economia)
print(portugues)
{'Fernanda', 'Igor', 'Juliana', 'Bruno', 'Diana', 'Gabriel', 'Ana', 'Eduardo', 'Helena', 'Carlos'}
{'Paula', 'Natália', 'Mariana', 'Lucas', 'Diana', 'Gabriel', 'Otávio', 'Rafael', 'Sofia', 'Carlos'}

Estudantes em ambas turmas simultaneamente (intersecção):

print(economia & portugues)
print(economia.intersection(portugues))
{'Diana', 'Gabriel', 'Carlos'}
{'Diana', 'Gabriel', 'Carlos'}

Estudantes em apenas uma das turmas (diferença simétrica):

print(economia ^ portugues)
print(economia.symmetric_difference(portugues))
{'Paula', 'Fernanda', 'Natália', 'Mariana', 'Igor', 'Juliana', 'Ana', 'Lucas', 'Bruno', 'Otávio', 'Eduardo', 'Rafael', 'Sofia', 'Helena'}
{'Paula', 'Fernanda', 'Natália', 'Mariana', 'Igor', 'Juliana', 'Ana', 'Lucas', 'Bruno', 'Otávio', 'Eduardo', 'Rafael', 'Sofia', 'Helena'}

Todos/as os/as estudantes (união):

print(economia | portugues)
print(economia.union(portugues))
{'Paula', 'Fernanda', 'Natália', 'Igor', 'Juliana', 'Bruno', 'Diana', 'Gabriel', 'Ana', 'Eduardo', 'Helena', 'Carlos', 'Rafael', 'Mariana', 'Lucas', 'Otávio', 'Sofia'}
{'Paula', 'Fernanda', 'Natália', 'Igor', 'Juliana', 'Bruno', 'Diana', 'Gabriel', 'Ana', 'Eduardo', 'Helena', 'Carlos', 'Rafael', 'Mariana', 'Lucas', 'Otávio', 'Sofia'}

set
Exercícios

Suponhas que as/os estudantes de economia e portugues tenham as seguintes matrículas:

  • economia: 101, 102, 103, 104, 105, 106, 107, 108, 109, 110.
  • portugues: 105, 106, 111, 112, 113, 104, 115, 116, 117, 118.

  • Crie dois set: uma para os matrículas de economia, e outra para os matrículas de portugues.
  • Verifique se existe intersecção entre os dois set.
  • Obtenha as matrículas de estudantes em apenas uma turma.

dicionário (dict)

  • Coleção de pares de objetos no padrão chave: valor. Semelhante a estrutura JSON.
  • Cada chave está associada com um único valor.
  • Um valor pode ser recuperado, deletado ou atualizado usando chave.
  • Usamos {} para criar um dicionário.
  • Podemos a função dict para converter:
    • lista de listas com dois objetos em dicionário (primeiro objeto será a chave, e o segundo objeto será a chave)
    • tupla de tuplas com dois objetos em dicionário (primeiro objeto será a chave, e o segundo objeto será a chave)

Dicionário (dict) - métodos

Métodos para um objeto dict.
Método Descrição
clear() Apaga todos os pares de um dicionário
copy() Produz uma cópia de um dicionário
fromkeys() Cria um dicionário usando vários chaves e um único valor.
get() Recupera um valor a partir da chave.
items() Retorna uma lista de tuplas em que o primeiro objeto é chave e o segundo objeto é o valor
keys() Retorna a lista com todas as chaves
pop() Remove um par chave: valor usando uma chave
popitem() Remove o último par chave: valor inserido no dicionário
setdefault(key, valor_padrao) Se key\(\in\)dict.keys(), então o valor da chave key é retornado. Caso contrário, key: valor_padrao é adicionado ao dicionário e valor_padrao é retornado.
update() Atualiza (e acrescenta) o(s) par(es) chave: valor
values() Retorna a lista com todos os valores

Dicionário (dict)
Exemplo

Transformando tupla de tuplas em dicionário.

equipe_lista = (
  ('coordenação', ['Profa. Carolina', 'Prof. Gilberto']),
  ('bolsista_voluntaria', ['Miguel', 'Mayara', 'Carol', 'Fernanda', 'Keila'])
)
equipe_dicionario = dict(equipe_lista)
print(equipe_dicionario)
{'coordenação': ['Profa. Carolina', 'Prof. Gilberto'], 'bolsista_voluntaria': ['Miguel', 'Mayara', 'Carol', 'Fernanda', 'Keila']}

Criando um dicionário usando {}.

equipe_dicionario = {
  'coordenação': ['Profa. Carolina', 'Prof. Gilberto'],
  'bolsista_voluntaria': ['Miguel', 'Mayara', 'Carol', 'Fernanda', 'Keila']
}
print(equipe_dicionario)
{'coordenação': ['Profa. Carolina', 'Prof. Gilberto'], 'bolsista_voluntaria': ['Miguel', 'Mayara', 'Carol', 'Fernanda', 'Keila']}

Dicionário (dict)
Exemplo

Produzindo uma lista de tuplas (com dois objetos) a partir de um dicionário.

equipe_dicionario.items()
dict_items([('coordenação', ['Profa. Carolina', 'Prof. Gilberto']), ('bolsista_voluntaria', ['Miguel', 'Mayara', 'Carol', 'Fernanda', 'Keila'])])

Pegando apenas as chaves.

equipe_dicionario.keys()
dict_keys(['coordenação', 'bolsista_voluntaria'])

Pegando apenas os valores.

equipe_dicionario.values()
dict_values([['Profa. Carolina', 'Prof. Gilberto'], ['Miguel', 'Mayara', 'Carol', 'Fernanda', 'Keila']])

Recuperando apenas um valor usando .get.

Se a chave existem entre as chaves, imprimi valor correspondente.

# 
print(equipe_dicionario.get('coordenação', 'Sem informação'))
['Profa. Carolina', 'Prof. Gilberto']

Se a chave não existe entre as chaves, imprimi valor padrão.

print(equipe_dicionario.get('Paz entre nós', 'Guerra aos senhores'))
Guerra aos senhores

Dicionário (dict)
Exercício

Crie um dicionário quatro chaves: matricula_economia, nome_economia, matricula_portugues e nome_portugues. Cada chave terá uma lista de valores correspondente que está listada abaixo:

  • Matrícula de estudantes de economia: 101, 102, 103, 104, 105, 106, 107, 108, 109, 110.
  • Matrícula de estudantes de português: 105, 106, 111, 112, 113, 104, 115, 116, 117, 118.
  • Nome de estudantes de economia: Ana, Bruno, Carlos, Diana, Eduardo, Fernanda, Gabriel, Helena, Igor, Juliana.
  • Nome de estudantes de português: Carlos, Diana, Lucas, Mariana, Natália, Otávio, Paula, Rafael, Sofia, Gabriel.

Estrutura de dados
numpy

NumPy

  • numpy: fundamental e crucial para análise de dados usando python.
  • Permite operações de álgebra linear: matrizes e vetores.
  • Extremamente rápido e eficiente que as estruturas de dados built-in
  • Todos pacotes para ciência de dados usam o numpy, incluindo pandas, scipy, scikit-learn e outros.
  • numpy armazena os dados de forma contígua na memória.
  • numpy permite a vetorização.

Array

  • Armazém rápido e eficiente para valores escalares de mesmo tipo (apenas um tipo).
  • Permite operações de álgebra linear (semelhantes a operações com valores escalares).

Podemos criar um array usando:

  • função np.array: converte lista e tupla em arrays.
  • funções especiais:
    • np.zeros(tupla ou lista de inteiros): crie matriz com zeros.
    • np.diag(tupla ou lista): cria um matriz diagonal.
    • np.eye: matriz identidade.
    • np.ones(tupla ou lista de inteiros): cria matriz com uns.
    • np.arange(inicio, fim, passo): cria valores em sequência. Valores criados estão no intervalo \([inicio, fim)\).

Tipo de dados em NumPy

  • Fonte de flexibilidade e do poder do NumPy.
  • Gerenciamento eficiente de memória.
  • Podemos mudar o tipo de dados de um array usando o método as.type.
Principais tipo de dados para arrays.
Tipo Código Descrição
int64 i8 Números inteiros
float64 f8 ou d Números reais
bool Valor lógico: True ou False
string_ S Texto em ASCII - tamanho fixo
unicode_ U Texto em unicode - tamanho fixo

Carregando o pacote NumPy:

import numpy as np

Array - exemplo

array_1 = np.array([[1, 20], [23, 22]])
array_2 = 10 * np.ones((2, 2))
print(f'array_1:\n {array_1}')
print(f'array_2:\n {array_2}')
array_1:
 [[ 1 20]
 [23 22]]
array_2:
 [[10. 10.]
 [10. 10.]]

Soma:

array_1 + array_2
array([[11., 30.],
       [33., 32.]])

Subtração:

array_1 - array_2
array([[-9., 10.],
       [13., 12.]])

Multiplicação:

array_1 * array_2
array([[ 10., 200.],
       [230., 220.]])

Divisão:

array_1 / array_2
array([[0.1, 2. ],
       [2.3, 2.2]])

Potenciação:

array_1**2
array([[  1, 400],
       [529, 484]])

Desigualdade:

array_1 > array_2
array([[False,  True],
       [ True,  True]])

Array - exemplo

Checando tipo de dados de um array:

array_1.dtype
dtype('int64')

Convertendo o tipo de dados:

array_real = array_1.astype(np.float64)
print(f'array_real: {array_real.dtype}')
print((f'array_1: {array_1.dtype}'))
array_real: float64
array_1: int64

De ASCII para Unicode:

nomes = np.array(['Juliana', 'Josefina', 'Joana'], dtype = "S")
nomes_u = nomes.astype(np.unicode_)
print(f'nomes: {nomes.dtype}')
print(f'nomes_u: {nomes_u.dtype}')
nomes: |S8
nomes_u: <U8

Array - slicing e índices

  • Usamos [] para selecionar elementos de um array.
    • Vetores: array[inicio:fim:passo] ou array[posicao].
    • Matrizes: array[inicio:fim:passo, inicio:fim:passo], array[linha, coluna] ou array[linha][coluna].
    • Matriz é uma coleção de linhas (vetores).
  • Podemos substituir inicio:fim por uma lista, tupla ou array de números inteiros.
  • Podemos omitir inicio e fim.
    • linha e coluna podem ser números inteiros ou valores lógicos.
    • se forem fornecidas linha e coluna, linha e coluna precisam ter o mesmo tamanho.
    • Exemplo: se linha = [0, 3, 1] e coluna = [2, 1, 3], então os valores (0, 2), (3, 1) e (1, 3).

Slicing cria uma view!
Use o método copy() para criar um cópia.

Array - slicing e índices
Exemplo

Exemplo:

array = np.array([[ 9.03, 10.53,  7.9 ],
       [10.93,  9.38,  9.52],
       [12.05, 11.82, 10.7 ]])

Ilustração, slicing e dimensão.

Ilustração, slicing e dimensão.

Array - slicing e índices

  • Indexação booleana: seleção de linhas/colunas usando operadores lógicos.
  • Indexação booleana: uso de lista (ou array) do tipo np.bool para selecionar linha/colunas.
    • Precisam ter o mesmo tamanho da linha/coluna.
array = np.array([[24.2, 25.3, 25.9, 23.4, 23.1],
                 [27.2, 24.1, 24. , 23.4, 26.4],
                 [27. , 24.4, 26.7, 24.1, 25.9],
                 [24.4, 24.9, 26.2, 25.1, 26.7],
                 [24.9, 26.9, 26. , 23.1, 25. ]])
array.shape
(5, 5)

Selecionando valores da primeira e coluna maiores que 25 (média):

array[[True, True, False, False, False]]
array([[24.2, 25.3, 25.9, 23.4, 23.1],
       [27.2, 24.1, 24. , 23.4, 26.4]])

Array - slicing e índices

Podemos usar operadores lógicos com indexação booleana:

  • \(>\) (menor), \(<\) (maior), \(\le\) (menor ou igual), \(\ge\) (maior ou igual), \(==\) (igual) e \(!=\) (diferente);
  • \(\sim\) (negação - True vira False e False vira True), \(\&\) (and) e \(|\) (ou).

Exemplo:

  • Cada linha é um/uma estudante;
  • Cada coluna é nota de uma disciplina.
dados = np.array([[9.18, 8.56, 8.96, 7.72, 6.68, 8.48, 8.93],
               [6.85, 7.76, 9.99, 8.21, 9.13, 7.67, 9.42],
               [9.78, 9.65, 9.39, 6.91, 8.07, 6.77, 9.69],
               [8.07, 9.19, 6.96, 6.49, 8.79, 8.23, 7.98],
               [7.95, 7.11, 9.59, 9.86, 9.66, 6.18, 7.65]])

estudantes = np.array(["Ana", "Bruno", "Carla", "Diego", "Elisa"])


# Notas dos homens
dados[(estudantes == "Bruno") | (estudantes == "Diego")]
array([[6.85, 7.76, 9.99, 8.21, 9.13, 7.67, 9.42],
       [8.07, 9.19, 6.96, 6.49, 8.79, 8.23, 7.98]])

Array - funcções universais

  • ufunc: realiza operações matemáticas sem usar laços de repetição.
  • Implementação rápida e eficiente de operações em arrays.

ufunc com apenas um argumento.
Função Descrição
abs Valor absoluto de cada elemento de um array
ceil Arrendonda para cima
floor Arrendonda para baixo
isnan Retorna True se o valor é missing
isfinite, isinf Retorna True se o valor é finito ou infinito
max Valor máximo de um array
min Valor mínimo de um array
ufunc com dois argumentos.
Função Descrição
add Adição elemento a elemento de dois arrays
multiply Multiplicação elemento a elemento de dois arrays
maximum, fmax maximum - máximo elememento a elemento de duas matrizes; fmax máximo elememento a elemento de duas matrizes ignora valores np.nan
minimum, fmin minimum - mínimo elememento a elemento de duas matrizes; fmin mínimo elememento a elemento de duas matrizes ignora valores np.nan

Array - Exercício

As calouras Ana, Bruna, Carla, Helena, e Elisa cursaram os componentes currículares estatística e português, e obtiveram as seguintes notas:

\[ \text{estatística} = \begin{pmatrix} 8,0 & 9,3 & 5,7 & 6,4 & 7,8 \end{pmatrix}^\top \]

\[ \text{português} = \begin{pmatrix} 8,5 & 7,2 & 9,0 & 6,8 & 7,5 \end{pmatrix}^\top \]


  • Qual a nota de estatística Helena em português e estatística?
  • Obtenha a maior nota de cada estudante?
  • Obtenha a menor nota de cada estudante?
  • Qual a maior nota de português?
  • Qual a menor nota de estatística?

pandas

Sobre pandas

  • Estrututura de dados para análise de dados em python.
  • Construído em cima de NumPy em 2008.
  • Series (estrutura unidimensional homogênero) e DataFrame (estrutura bidimensional heterogêneo).
  • Usado por todos pacotes de Estatística e Ciência de Dados em python.
  • Valores faltantes: np.nan, pd.NA e None.
  • Outros valores especiais: np.inf e -np.inf.

import pandas as pd
from pandas import Series, DataFrame

Series

Series

  • Estrutura unidimensional e homogênea no estilo array-like.
  • Composto por:
    • array: dados organizados em array. Pode ter nome.
    • index: índice para acesso rápido e eficiente. Pode ter nome.
  • to_dict(): converte Serie para dicionário.
nomes = Series(data = ["Ana", "Bruna", "Carla", "Helena", "Elisa"],
              index = [20231578, 40321789, 50284613, 30897541, 71239064])
nomes.name = "nomes"
nomes.index.name = "matrícula"
print(nomes)
matrícula
20231578       Ana
40321789     Bruna
50284613     Carla
30897541    Helena
71239064     Elisa
Name: nomes, dtype: object

Podemos acessar os dados com atributo array:

nomes.array
<NumpyExtensionArray>
['Ana', 'Bruna', 'Carla', 'Helena', 'Elisa']
Length: 5, dtype: object

Podemos acessar o índice com atributo index:

nomes.index
Index([20231578, 40321789, 50284613, 30897541, 71239064], dtype='int64', name='matrícula')

De uma Series para dicionário:

nomes.to_dict()
{20231578: 'Ana',
 40321789: 'Bruna',
 50284613: 'Carla',
 30897541: 'Helena',
 71239064: 'Elisa'}

Series - slicing

  • [---]:
    • --- pode ser valores ou lista/tupla de valores do índice.
    • --- pode ser valores lógicos.
  • Operações básicas e funções universais funcionam para Series.

nomes = Series(data = [7.4 , 7.84, 9.64, 9.32, 8.64],
              index = [20231578, 40321789, 50284613, 30897541, 71239064])
nomes.name = "CR"
nomes.index.name = "matrícula"

Operações básicas e funções universais:

# nota média
print(np.mean(nomes))
8.568000000000001
# apenas as maiores notas
print(nomes[nomes > 9])
matrícula
50284613    9.64
30897541    9.32
Name: CR, dtype: float64

Series
Exercício

Considere cinco candidatas/os do no ENEM 2023 com matrícula : 210058437213, 210059138190, 210058459503, 210061875001, 210059087534. As notas em Matemática dessas/es estudantes foram 410,6; 615,8; 460,9; 509; 516,3; e as notas em Ciências Naturais dessas/es estudantes foram 506,1; 483,3; 520,4; 492,3; 593,3.

  • Crie uma Serie para as notas de Matemática.
  • Crie uma Serie para as notas de Ciências Naturais.
  • Calcule a média de Matemática (use np.mean).
  • Calcule a média de Ciências Naturais (use np.mean)

DataFrame

Alguns conceitos básicos de estatística

  • População: todos os elementos ou indivíduos alvo do estudo.
  • Amostra: parte da população.
  • Parâmetro: característica numérica da população. Usamos letras gregas para denotar parâmetros populacionais.
  • Estatística: agregação.
  • Estimativa: característica numérica da amostra, obtida da estatística computada na amostra. Em geral, usamos uma estimativa para estimar o parâmetro populacional.
  • Variável: característica mensurável comum a todos os elementos da população.

Alguns conceitos básicos de estatística

Classificação de variáveis.

Alguns conceitos básicos de estatística
Exemplo

  • População: todos os eleitores nas eleições gerais de 2023.
  • Amostra: 3.500 pessoas abordadas pelo datafolha.
  • Variável: candidato a presidente de cada pessoa.
  • Parâmetro: porcentagem de pessoas que escolhem Lula como presidente entre todos os eleitores.
  • Estatística: porcentagem de pessoas que escolhem o lula.
  • Estimativa: porcentagem de pessoas que escolhem Lula como presidente entre todos os eleitores da amostra de 3.500 pessoas entrevistas pelo datafolha.

DataFrame

  • Dados em estrutura tabular:
    • Cada linha tem uma única observação.
    • Cada coluna tem uma única variável.
    • Cada coluna é um objeto Serie.
    • Existe um índice para as colunas e um índice para as linhas.
      • index: índice para linhas.
      • columns: índice para colunas.
Como criar um DataFrame na mão.
Tipo Notas
2D ndarray Array bidimensional
Dicionário of arrays, lists, or tuples Cada sequência é uma coluna
Dicionário de Serie Cada Serie será uma coluna; índices de cada Serie são unidos se nenhum índice é explicitamente fornecido
Lista de listas ou tuplas Semelhante 2D ndarray

DataFrame

estudantes = DataFrame({
  'nu_nota_mt': [581.5, 466.1, 753.4, 389.2, 611.5],
  'nu_nota_cn': [489.1, 532.7, 545.5, 489.6, 487.5]
}, index  = [2, 4, 6, 8, 10])
estudantes.index.name = 'num_inscricao'

estudantes
nu_nota_mt nu_nota_cn
num_inscricao
2 581.5 489.1
4 466.1 532.7
6 753.4 545.5
8 389.2 489.6
10 611.5 487.5

Índice - Serie e DataFrame

  • armazena índice das linhas/colunas.
  • .loc[]: acessar um valor da linha/coluna pelo texto do índice.
  • iloc[]: acessar um elemento da linha/coluna pela sequência.
  • Podemos usar a síntaxe de slicing e indexing de arrays.
    • A contagem começa no zero.

Usando .loc:

print(estudantes.loc[2])
nu_nota_mt    581.5
nu_nota_cn    489.1
Name: 2, dtype: float64
print(estudantes.loc[2, :])
nu_nota_mt    581.5
nu_nota_cn    489.1
Name: 2, dtype: float64
print(estudantes.loc[2, 'nu_nota_mt'])
581.5

Usando iloc:

print(estudantes.iloc[2])
nu_nota_mt    753.4
nu_nota_cn    545.5
Name: 6, dtype: float64
print(estudantes.iloc[2, :])
nu_nota_mt    753.4
nu_nota_cn    545.5
Name: 6, dtype: float64
print(estudantes.iloc[2, 1])
545.5

Sobre [] - DataFrame

Seleção de linhas e/ou coluns, e um único valor.
df é um objeto DataFrame.
Tipo
df[column] Seleciona uma coluna ou uma sequência de colunas. Caso column seja uma sequência de valores lógicos, linhas são selecionadas (de forma parecida array)
df.loc[rows] Seleciona uma única linha ou um conjunto de linhas
df.loc[:, cols] Seleciona uma ou mais colunas pelo rótulo
df.loc[rows, cols] Seleciona linhas e/ou colunas pelo rótulo
df.iloc[rows] Seleciona uma ou mais linhas de um DataFrame pela posição
df.iloc[:, cols] Seleciona uma ou mais colunas pela posição
df.iloc[rows, cols] Seleciona linhas e/ou colunhas pela posição
df.at[row, col] Seleciona um único valor escalar pelo rótulo da linha e da coluna
df.iat[row, col] Seleciona um único valor escalar pela posição da linha e da coluna

Sobre [] - Serie

Seleção de objetos de Serie, e um único valor.
sr é um objeto Serie.
Tipo
sr[rows] Seleciona objeto(s) usando um ou mais rótulos. Caso rows seja uma sequência de valores lógicos, valores são selecionadas (de forma parecida array)
sr.loc[rows] Seleciona objeto(s) usando um ou mais rótulos.
sr.iloc[rows] Seleciona objeto(s) usando um ou mais rótulos pela posição.
sr.at[row] Seleciona um único valor escalar pelo rótulo
sr.iat[row] Seleciona um único valor escalar pela posição

Sobre [] - Exemplo

[] - DataFrame.

estudantes.loc[[2, 4], 'nu_nota_mt']
num_inscricao
2    581.5
4    466.1
Name: nu_nota_mt, dtype: float64
estudantes.iloc[[0, 1], 0]
num_inscricao
2    581.5
4    466.1
Name: nu_nota_mt, dtype: float64
estudantes.at[2, 'nu_nota_mt']
581.5
estudantes.iat[0, 0]
581.5

[] - Serie.

nu_nota_mt = estudantes.nu_nota_mt
nu_nota_mt.loc[[2, 4]]
num_inscricao
2    581.5
4    466.1
Name: nu_nota_mt, dtype: float64
nu_nota_mt.iloc[[0, 1]]
num_inscricao
2    581.5
4    466.1
Name: nu_nota_mt, dtype: float64
nu_nota_mt.at[2]
581.5
nu_nota_mt.iat[0]
581.5

Sobre []
Exercício

Considere cinco estudantes com matrículas 210058894852, 210060690421, 210061408626, 210058862425 e 210059157480.

  • Crie um objeto Serie com as notas em português (nu_nota_lc): 461,9; 528,5; 413,9; 516,2; 679,3.
  • Crie um objeto Serie com as notas em ciências humanas (nu_nota_ch): 344,6; 612,2; 359,2; 496,9; 681,7.
  • Crie um DataFrame com as duas Serie.

Importação e exportação
arquivos csv e xlsx

csv: comma separated values

Diferenças entre o sistema métrico e o sistema imperial.
Função No Brasil No EUA
Casa decimal 1000,53 1000.53
Agrupador de milhar 1.000,53 1,000.53
Separador de colunas ; ,

Função para leitura:

  • No Brasil: pd.read_csv(filename.csv, sep = ";", decimal = ",", thousands = ".")
  • No EUA: pd.read_csv(filename.csv)

Importação e exportação - arquivos csv e xlsx

Exemplo - csv

amostra_51 = pd.read_csv("dados/brutos/amostra_51.csv")
print(amostra_51.shape)
print(amostra_51.columns)
(5000, 76)
Index(['nu_inscricao', 'nu_ano', 'tp_faixa_etaria', 'tp_sexo',
       'tp_estado_civil', 'tp_cor_raca', 'tp_nacionalidade', 'tp_st_conclusao',
       'tp_ano_concluiu', 'tp_escola', 'tp_ensino', 'in_treineiro',
       'co_municipio_esc', 'no_municipio_esc', 'co_uf_esc', 'sg_uf_esc',
       'tp_dependencia_adm_esc', 'tp_localizacao_esc', 'tp_sit_func_esc',
       'co_municipio_prova', 'no_municipio_prova', 'co_uf_prova',
       'sg_uf_prova', 'tp_presenca_cn', 'tp_presenca_ch', 'tp_presenca_lc',
       'tp_presenca_mt', 'co_prova_cn', 'co_prova_ch', 'co_prova_lc',
       'co_prova_mt', 'nu_nota_cn', 'nu_nota_ch', 'nu_nota_lc', 'nu_nota_mt',
       'tx_respostas_cn', 'tx_respostas_ch', 'tx_respostas_lc',
       'tx_respostas_mt', 'tp_lingua', 'tx_gabarito_cn', 'tx_gabarito_ch',
       'tx_gabarito_lc', 'tx_gabarito_mt', 'tp_status_redacao',
       'nu_nota_comp1', 'nu_nota_comp2', 'nu_nota_comp3', 'nu_nota_comp4',
       'nu_nota_comp5', 'nu_nota_redacao', 'q001', 'q002', 'q003', 'q004',
       'q005', 'q006', 'q007', 'q008', 'q009', 'q010', 'q011', 'q012', 'q013',
       'q014', 'q015', 'q016', 'q017', 'q018', 'q019', 'q020', 'q021', 'q022',
       'q023', 'q024', 'q025'],
      dtype='object')

Importação e exportação - arquivos csv e xlsx

Exemplo - xlsx

amostra_51 = pd.read_excel("dados/brutos/amostra_51.xlsx")
amostra_51.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5000 entries, 0 to 4999
Data columns (total 76 columns):
 #   Column                  Non-Null Count  Dtype  
---  ------                  --------------  -----  
 0   nu_inscricao            5000 non-null   int64  
 1   nu_ano                  5000 non-null   int64  
 2   tp_faixa_etaria         5000 non-null   object 
 3   tp_sexo                 5000 non-null   object 
 4   tp_estado_civil         5000 non-null   object 
 5   tp_cor_raca             5000 non-null   object 
 6   tp_nacionalidade        5000 non-null   object 
 7   tp_st_conclusao         5000 non-null   object 
 8   tp_ano_concluiu         5000 non-null   object 
 9   tp_escola               5000 non-null   object 
 10  tp_ensino               1914 non-null   object 
 11  in_treineiro            5000 non-null   object 
 12  co_municipio_esc        1341 non-null   float64
 13  no_municipio_esc        1341 non-null   object 
 14  co_uf_esc               1341 non-null   float64
 15  sg_uf_esc               1341 non-null   object 
 16  tp_dependencia_adm_esc  1341 non-null   object 
 17  tp_localizacao_esc      1341 non-null   object 
 18  tp_sit_func_esc         1341 non-null   object 
 19  co_municipio_prova      5000 non-null   int64  
 20  no_municipio_prova      5000 non-null   object 
 21  co_uf_prova             5000 non-null   int64  
 22  sg_uf_prova             5000 non-null   object 
 23  tp_presenca_cn          5000 non-null   object 
 24  tp_presenca_ch          5000 non-null   object 
 25  tp_presenca_lc          5000 non-null   object 
 26  tp_presenca_mt          5000 non-null   object 
 27  co_prova_cn             5000 non-null   object 
 28  co_prova_ch             5000 non-null   object 
 29  co_prova_lc             5000 non-null   object 
 30  co_prova_mt             5000 non-null   object 
 31  nu_nota_cn              5000 non-null   float64
 32  nu_nota_ch              5000 non-null   float64
 33  nu_nota_lc              5000 non-null   float64
 34  nu_nota_mt              5000 non-null   float64
 35  tx_respostas_cn         5000 non-null   object 
 36  tx_respostas_ch         5000 non-null   object 
 37  tx_respostas_lc         5000 non-null   object 
 38  tx_respostas_mt         5000 non-null   object 
 39  tp_lingua               5000 non-null   object 
 40  tx_gabarito_cn          5000 non-null   object 
 41  tx_gabarito_ch          5000 non-null   object 
 42  tx_gabarito_lc          5000 non-null   object 
 43  tx_gabarito_mt          5000 non-null   object 
 44  tp_status_redacao       5000 non-null   object 
 45  nu_nota_comp1           5000 non-null   int64  
 46  nu_nota_comp2           5000 non-null   int64  
 47  nu_nota_comp3           5000 non-null   int64  
 48  nu_nota_comp4           5000 non-null   int64  
 49  nu_nota_comp5           5000 non-null   int64  
 50  nu_nota_redacao         5000 non-null   int64  
 51  q001                    5000 non-null   object 
 52  q002                    5000 non-null   object 
 53  q003                    5000 non-null   object 
 54  q004                    5000 non-null   object 
 55  q005                    5000 non-null   int64  
 56  q006                    5000 non-null   object 
 57  q007                    5000 non-null   object 
 58  q008                    5000 non-null   object 
 59  q009                    5000 non-null   object 
 60  q010                    5000 non-null   object 
 61  q011                    5000 non-null   object 
 62  q012                    5000 non-null   object 
 63  q013                    5000 non-null   object 
 64  q014                    5000 non-null   object 
 65  q015                    5000 non-null   object 
 66  q016                    5000 non-null   object 
 67  q017                    5000 non-null   object 
 68  q018                    5000 non-null   object 
 69  q019                    5000 non-null   object 
 70  q020                    5000 non-null   object 
 71  q021                    5000 non-null   object 
 72  q022                    5000 non-null   object 
 73  q023                    5000 non-null   object 
 74  q024                    5000 non-null   object 
 75  q025                    5000 non-null   object 
dtypes: float64(6), int64(11), object(59)
memory usage: 2.9+ MB

Importação e exportação - arquivos csv e xlsx

  • Leia uma amostra de pessoas do Enem 2023 no formato .csv.
  • Leia uma amostra de pessoas do Enem 2023 no formato .xlsx.

Cada pessoa tem o seu próprio conjunto de dados no website.

Estatística descritiva

Tabela de distribuição de frequências
Variável qualitativa

A primeira coisa que podemos fazer é contar!

Tabela de distribuição de frequência para a variável qualitativa \(X\).
X frequência frequência relativa porcentagem
B1 n1 f1 p1
B2 n2 f2 p2
\(\vdots\) \(\vdots\) \(\vdots\) \(\vdots\)
Bk nk fk pk

em que ni, \(i=1, \dots, k\): frequência da categoria Bi; \(f_i = \frac{n_i}{n}\) é a frequência relativa da categoria Bi em que \(n\) é o tamanho da amostra; e \(p_i=f_i \cdot 100\) é a porcentagem da categoria Bi.

Tabela de distribuição de frequências
Variável qualitativa

Tabela de distribuição de frequência para in_treineiro.

Vamos usar o método value_counts().

frequencia = amostra_51['in_treineiro'].value_counts()
freq_rel = amostra_51['in_treineiro'].value_counts(normalize=True)
porcentagem = amostra_51['in_treineiro'].value_counts(normalize=True) * 100
tabela = DataFrame({
  'frequência': frequencia,
  'frequência relativa': freq_rel,
  'porcentagem': porcentagem
  }).sort_index()
tabela.to_excel('tabelas/tabela_distribuicao_frequencia.xlsx')
print(tabela)
              frequência  frequência relativa  porcentagem
in_treineiro                                              
Não                 4064               0.8128        81.28
Sim                  936               0.1872        18.72

Podemos criar uma função para construir uma tabela de distribuição de frequências:

def tab_freq(data, coluna):
  frequencia = data[coluna].value_counts()
  freq_rel = data[coluna].value_counts(normalize=True)
  porcentagem = data[coluna].value_counts(normalize=True) * 100
  tabela = DataFrame({
    'frequência': frequencia,
    'frequência relativa': freq_rel,
    'porcentagem': porcentagem
    }).sort_index()
  return tabela

print(tab_freq(amostra_51, 'in_treineiro'))
              frequência  frequência relativa  porcentagem
in_treineiro                                              
Não                 4064               0.8128        81.28
Sim                  936               0.1872        18.72

Tabela de distribuição de frequências
Variável qualitativa
Exercício

Calcule a tabela de distribuição de frequência para as variáveis:

  • tp_sexo
  • tp_cor_raca

para uma amostra de candidatas/os do Enem 2023. Cada pessoa tem sua amostra Enem 2023.

Tabela de distribuição de frequências
Variável quantitativa discreta

É possível construir tabela de distribuição de frequência para variável quantitativa discreta.

carros = pd.read_csv("dados/brutos/mtcarros.csv")
tab_freq(carros, 'marchas')
frequência frequência relativa porcentagem
marchas
3 15 0.46875 46.875
4 12 0.37500 37.500
5 5 0.15625 15.625

Tabela de distribuição de frequências
Variável quantitativa discreta
Exercício

Construa uma tabela de distribuição de frequências para a variável q005 (número de pessoas que moram com a/o candidata/o incluindo a/o candidata/o) para uma amostra Enem 2023.

Cada pessoa tem sua própria amostra.

Tabela de distribuição de frequências
Variável quantitativa contínua

  • Tabelas não podem tem muitas linhas.
    • Se tiver, agrupe os valores em faixas.
print(tab_freq(amostra_51, 'nu_nota_cn'))
            frequência  frequência relativa  porcentagem
nu_nota_cn                                              
0.0                 24               0.0048         0.48
323.6                2               0.0004         0.04
323.8                1               0.0002         0.02
324.4                1               0.0002         0.02
324.8                1               0.0002         0.02
...                ...                  ...          ...
779.6                1               0.0002         0.02
795.1                1               0.0002         0.02
808.4                1               0.0002         0.02
831.8                1               0.0002         0.02
853.8                1               0.0002         0.02

[2465 rows x 3 columns]

Tabela de distribuição de frequências
Variável quantitativa contínua

Tabela de distribuição de frequências para uma variável quantitativa contínua X.
X frequência frequência relativa porcentagem
[l0, l1) n1 f1 p1
[l1, l2) n2 f2 p2
[l2, l3) n3 f3 p3
\(\vdots\) \(\vdots\) \(\vdots\) \(\vdots\)
[lk-1, lk] nk fk pk
  • []: valor que acompanha entra na contagem;
  • (): valor que acompanha não entra na contagem.
  • menor valor de X = \(l_0 \leq l_1 \leq l_2 \leq \cdots \leq l_{k−1} \leq l_k\) = maior valor de X;
  • \(n_i\) é número de valores de X entre \(l_{i−1}\) e \(l_i\);
  • \(l_0, l_1, \cdots , l_k\) quebram o suporte da variável X (breakpoints);
  • \(l_0, l_1, \cdots , l_k\) são escolhidos pelo analista.

Recomendações:

  • use \(l_0, l_1, \cdots , l_k\) igualmente espaçados;
  • e use a regra de Sturges para determinar o valor de k:
  • \(k = \lceil 1 + \log2(n)\rceil\) onde n é tamanho da amostra.

Tabela de distribuição de frequências
Variável quantitativa contínua

  • pd.cut: agrega valores numéricos em faixa de valores. Argumentos:
    • bins: critério para construção das faixas
      • bins = k: cria k intervalos de mesmo tamanho. k precisa ser um valor inteiro.
      • bins = lista: usa os valores de lista como breakpoints
    • right: False para não incluir o valor da direita na contagem
    • include_lowest: True para incluir o valor da esquerda na contagem
    • labels: rótulos customizados para as faixas de valores

Tabela de distribuição de frequências
Variável quantitativa contínua

Definindo breakpoints: 0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000.

amostra_51['faixa_nu_nota_cn'] = pd.cut(
  amostra_51['nu_nota_cn'],
  bins = np.arange(0, 1001, 100),
  right = False, 
  include_lowest = True,
  labels = [
    "de 0 a 99,99", "de 100 a 199,99", "de 200 a 299,99",
    "de 300 a 399,99", "de 400 a 499,99", "de 500 a 599,99",
    "de 600 a 699,99", "de 700 a 799,99", "de 800 a 899,99", "de 900 a 1000"
  ]
)
amostra_51[['nu_nota_cn', 'faixa_nu_nota_cn']].head(n=3)
nu_nota_cn faixa_nu_nota_cn
0 398.6 de 300 a 399,99
1 412.7 de 400 a 499,99
2 495.6 de 400 a 499,99

Tabela de distribuição de frequências
Variável quantitativa contínua

Usando a regra de Sturge.

k = np.ceil(1 + np.log2(amostra_51.shape[0]))
k = k.astype(np.int64)
amostra_51['faixa_nu_nota_ch'] = pd.cut(
  amostra_51['nu_nota_ch'],
  bins = k,
  right = False, 
  include_lowest = True
)
amostra_51[['nu_nota_ch', 'faixa_nu_nota_ch']].head(n=3)
nu_nota_ch faixa_nu_nota_ch
0 534.6 [504.064, 560.071)
1 397.4 [392.05, 448.057)
2 481.2 [448.057, 504.064)

Tabela de distribuição de frequências
Variável quantitativa contínua

Calcule a tabela de distribuição de frequência para as variáveis:

  • nu_nota_mt (nota de matemática) usando a regra de Sturge;
  • nu_nota_lc (nota de português) usando os breakpoints 0, 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800, 850, 900, 950, 1000;

para uma amostra de candidatas/os do Enem 2023. Cada pessoa tem sua amostra Enem 2023.

Gráficos

matplotlib

Gráficos

  • Transformar tabelas em figuras geométricas.
    • Seres humanos interpretam velozmente figuras geométricas.

matplotlib

  • Ideia era copiar gráficos do MATLAB, e surgiu em 2002.
  • Projeto enorme com diversas opções para produzir a mesma figura geométrica.
  • Existem vários pacotes que usam matplotlib.
  • seaborn: simplifica a sintaxe do matplotlib (criado em 2012).
import matplotlib.pyplot as plt
import seaborn as sns

Estrutura básica

fig, ax = plt.subplots(nrows, ncols, figsize=(12, 10))
sns.<figura geométrica>(data=<objeto DataFrame>, x = "variável", y = "variável", ax=ax)
ax.set_xlabel("texto no eixo x")
ax.set_ylabel("texto no eixo y")
ax.set_xticks(<lista de valores>)
ax.set_xtickslabels(<lista de textos>, rotation=90, fontsize=8)
ax.set_yticks(<lista de valores>)
ax.set_ytickslabels(<lista de textos>, rotation=90, fontsize=8)
ax.set_title(<texto>)
ax.set_xlim([1, 100])
ax.set_ylim([1, 100])
ax.legend() # adiciona legenda
fig.savefig("nome da figura.png")
  • fig: local onde reside a figura geométrica produzida;
  • ax: local onde controlamos os elementos da figura geométrica.

Gráfico de barras

sns.countplot

  • Adequado para:
    • Variável qualitativa
    • Variável quantitativa discreta (com poucos valores)
  • Cada categoria (ou valor) é representada por uma barra.
  • Largura da barra não importa.
  • Existe espaço entre as barras.
  • Altura da barra é a frequência, frequência relativa ou porcentagem:
    • stat = 'count': altura da barra é a frequência.
    • stat = 'proportion': altura da barra é a frequência relativa.
    • stat = 'percent': altura da barra é a porcentagem.

Gráfico de barras

in_treineiro da amostra de Enem 2023.

amostra_51 = pd.read_csv("dados/brutos/amostra_51.csv")
fig, ax = plt.subplots(figsize=(5, 3))
sns.countplot(data=amostra_51, x='in_treineiro', stat='percent', color="#212335", ax=ax)
ax.set_xlabel("Candidata/o treineira/o?")
ax.set_ylabel("Porcentagem")
plt.show()
fig.savefig("figuras/grafico_treineiro.png")
fig.savefig("figuras/grafico_treineiro.pdf")

Gráfico de barras
Exercício

Construa os seguintes gráficos de barras para a amostra Enem 2023:

  1. Variável tp_sexo (gênero da pessoa) e a altura da barra é a frequência.
  2. Variável tp_cor_raca (cor/raça da pessoa) e a altura da barra é a frequência relativa.
  3. Variável q005 (número de pessoas que moram com o candidata/o) e a altura da barra é a porcentagem.

Salve todas as figuras no formato png.

Cada pessoa tem sua própria amostra.

Histograma

  • Adequado para:
    • variável quantitativa contínua.
    • variável quantitativa discreta com muitos valores distintos.
  • Não existe espaço entre as barras.
  • A largura da barra da faixa \([l_{i-1}, l_i)\) precisa ser proporcional a \(l_i - l_{i-1}\).
  • Existem duas formas de construir histograma:

Informação está na altura da barra.

Padrão adotado por alguns cientistas da computação.

  • stat='count': altura da barra é frequência.
  • stat='proportion': altura da barra é frequência relativa.

Informação está na área da barra.

Padrão adotado pela Estatística.

  • stat='frequency': área da barra é frequência.
  • stat='density': área da barra é frequência relativa.

Ilustração do caso stat='density': área da barra \([l_{i-1}, l_i)\) é a frequência relativa \(f_i\).

Histograma e intervalos

sns.histplot

Formas de especificar os intervalos:

  1. Número de intervalos (regra de Sturge): bins = k
    • k é um número inteiro
    • todos intervalos têm mesmo tamanho
  2. Breakpoints dos intervalos: bins = lista
    • lista é uma lista com breakpoints
  3. Tamanho de cada intervalos: binwidth = tam
    • tam é um número real que representa o tamanho dos intervalos
    • todos intervalos têm mesmo tamanho

Histograma
stat='count' e bins='lista'

  • nu_nota_cn da amostra Enem 2023
  • a frequência é a altura da barra
  • intervalos: 0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000
breakpoints = [0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000]
amostra_51 = pd.read_csv("dados/brutos/amostra_51.csv")
fig, ax = plt.subplots(figsize = (5, 3))
sns.histplot(data=amostra_51, x='nu_nota_cn', stat='count', bins=breakpoints, color='blue', ax=ax)
ax.set_xlabel('Nota de ciências naturais')
ax.set_ylabel('Frequência')
ax.set_xticks(breakpoints)
plt.show()

Histograma em que a altura da barra é a frequência.

Histograma
stat='density' e bins=k

  • nu_nota_ch da amostra Enem 2023
  • a frequência relativa é a área da barra
  • número de intervalos: regra de Sturge
amostra_51 = pd.read_csv("dados/brutos/amostra_51.csv")
# regra de sturge
k = np.ceil(1 + np.log2(amostra_51.shape[0]))
k = k.astype(np.int64)

fig, ax = plt.subplots(figsize = (5, 3))
sns.histplot(data=amostra_51, x='nu_nota_ch', stat='density', bins=k, color='blue', ax=ax)
ax.set_xlabel('Nota de ciências naturais')
ax.set_ylabel('Densidade de frequência')
plt.show()

Histograma em que a área da barra é a frequência relativa.

Histograma
Exercício

Crie os seguintes histogramas para a amostra Enem 2023:

  • variável quantitativa contínua nu_nota_mt (nota de matemática) com densidade de frequência no eixo y (stat='density') e use a regra de Sturge (bins='k');
  • variável quantitativa contínua nu_nota_mt (nota de matemática) com densidade de frequência no eixo y (stat='density') e use intervalos de tamanho 50 pontos (binwidth=50);
  • variável quantitativa contínua nu_nota_lc (nota de português) com frequência no eixo y (stat='count') e use intervalos de tamanho 50 pontos (binwidth=50);
  • variável quantitativa contínua nu_nota_lc (nota de português) com porcentagem no eixo y (stat='percent') e use intervalos de tamanho 50 pontos (binwidth=50).

Medidas resumo

Medidas de resumo

A ideia é encontrar um ou alguns valores que sintetizem todos os valores.


Medidas de posição

Um número que representa bem todos os números.

Principais medidas de posição: média, mediana, e moda.

Média

Média é a soma dos valores dividido pela quantidade de valores que foram somados.

Ilustração da ideia de média: média é o centro de massa.

Mediana

  1. Ordene os valores do menor ao maior valor
  2. Pega o meio da fila

Ilustração da ideia de mediana: meio da fila.

Moda

Valor mais frequente.

Ilustração da ideia de moda: valor com a maior frequência.

Medidas de resumo - exemplo

marchasmtcarros.xlsx

carros = pd.read_csv("dados/brutos/mtcarros.csv")
tab_freq(carros, 'marchas')
frequência frequência relativa porcentagem
marchas
3 15 0.46875 46.875
4 12 0.37500 37.500
5 5 0.15625 15.625

A moda é 3: o mais comum é um carro ter 3 marchas.

Medidas de resumo são calculadas em duas etapas:

  • divida os dados em grupos (ou em um único grupo)
    • .groupby: divide um objeto data frame em partes
  • aplique alguma estatística com .agg
    • .agg: método para resumo de variáveis no formato:
{'nome da variável': <função ou nome da função ou lista>,  ..., 'nome da variável': <função ou nome da função ou lista>}

função precisa retornar um valor escalar.

def media(x):
  return sum(x) / len(x)
def zero(x):
  return 0
resumos = carros.groupby(zero).agg({
  'marchas': [('média', 'mean'), ('mediana', 'median')], 
  'carburadores': [media, 'max'],
  'milhas_por_galao': media
})
resumos
marchas carburadores milhas_por_galao
média mediana media max media
0 3.6875 4.0 2.8125 8 20.090625

Agrupamento com groupby

A etapa de agrupamento pode ser feita de três formas:

  1. uma string ou lista de string de nomes das colunas
  2. uma lista do tamanho da amostra
  3. uma função que será aplicada a cada elemento do índice do data frame
df_equipe = pd.DataFrame({
  "pesos": [70.5, 82.1, 65.3, 90.0, 75.8, 68.7, 78.2],
  "alturas": [1.75, 1.82, 1.68, 1.90, 1.72, 1.65, 1.80],
  "vinculo": ["Docente", "Docente", "estudante", "estudante", "estudante", "estudante", "estudant"],
}, index = ["Profa Carolina", "Prof Gilberto", "Carol", "Miguel", "Keila", "Fernanda", "Mayara"])
df_equipe.index.name = "nome"

Agrupamento com groupby

Usando uma lista de colunas

df_equipe.groupby(['vinculo']).agg({
  "alturas": [("Média", 'mean'), ("Mediana", 'median')]
})
alturas
Média Mediana
vinculo
Docente 1.7850 1.785
estudant 1.8000 1.800
estudante 1.7375 1.700

Agrupamento com groupby

Usando uma lista com o mesmo tamanho da amostra

genero = ['F', 'M', 'F', 'M', 'F', 'F', 'F']
df_equipe.groupby(genero).agg({
  'alturas': ['mean', 'median']
})
alturas
mean median
F 1.72 1.72
M 1.86 1.86

Agrupamento com groupby

Usando uma função

Agrupamento pelo número de caracteres dos nomes.

df_equipe.groupby(len).agg({
  'alturas': ['mean', 'median', 'count']
})
alturas
mean median count
nome
5 1.70 1.70 2
6 1.85 1.85 2
8 1.65 1.65 1
13 1.82 1.82 1
14 1.75 1.75 1

Estatísticas em pandas

Algumas estatísticas de resumo implementadas no pacote pandas.
Nome da função Descrição
count Números de observações não faltantes
first, last Primeiro e último valor não faltantes
mean média de valores não faltantes
median Mediana de valores não faltantes
min, max Mínimo e máximo de valores não faltantes
prod Produto de valores não faltantes
sum Soma de valores não faltantes
std, var Desvio padrão e variância amostral dos valores não faltantes

Medidas de resumo
Exercício

Para uma amostra de Enem 2023 calcule:

  • Média e mediana de nota de matemática (nu_nota_mt) por raça/cor (tp_cor_raca);
  • Média e mediana de nota de português (nu_nota_lc) por raça/cor (tp_cor_raca).

Cada pessoa tem sua própria amostra.

Quantis

Quantil

Ideia:

\(q(p)\) é um valor que satisfaz:

  • \(100·p\%\) das observações são iguais ou abaixo de \(q(p)\);
  • \(100·(1−p)\%\) das observações são iguais ou acima de \(q(p)\).

Alguns casos especiais:

  • Primeiro quartil: \(q\left(\frac{1}{4}\right)\);
  • Segundo quartil: \(q\left(\frac{2}{4}\right)\);
  • Terceiro quartil: \(q\left(\frac{3}{4}\right)\).

Ilustração: primeiro, segundo e terceiro quartil.

Quantil

  • lambda: função anônima usada apenas uma vez:
    • lambda x: <conta que retorna um único valor>
carros = pd.read_csv("dados/brutos/mtcarros.csv")
def q1(x): 
  return np.quantile(x, 0.25)
tab = carros.groupby(lambda _: 0).agg({
  'marchas': [('min', 'min'),('q1', q1), ('mediana', lambda x: np.quantile(x, 0.5)), 
  ('q3', lambda x: np.quantile(x, 0.75)), ('max', 'max')]
})
tab
marchas
min q1 mediana q3 max
0 3 3.0 4.0 4.0 5

Quantil
Exercício

Para uma amostra de Enem 2023 calcule:

  • \(q(0,1)\), primeiro quartil, mediana, terceiro quartil, \(q(0,9)\) de nota de matemática (nu_nota_mt);
  • \(q(0,1)\), primeiro quartil, mediana, terceiro quartil, \(q(0,9)\) de nota de matemática (nu_nota_mt) por gênero (tp_sexo);
  • \(q(0,1)\), primeiro quartil, mediana, terceiro quartil, \(q(0,9)\) de nota de matemática (nu_nota_lc);
  • \(q(0,1)\), primeiro quartil, mediana, terceiro quartil, \(q(0,9)\) de nota de matemática (nu_nota_lc) por gênero (tp_sexo).

Cada pessoa tem sua própria amostra.

Diagrama de Caixa

Diferença de quartis

Medida de dispersão: distância entre o primeiro e o terceiros quartis.

\[ dq = q_3 - q_1. \]

Figura 3: Ilustração da diferença de quartis como medida de dispersão.

Diagrama de Caixa

  • LS (Limite Superior): \(LS = q_3 + 1,5 \cdot dq\).
  • LS (Limite Superior): \(LI = q_1 - 1,5 \cdot dq\).
  • Ponto exterior ou valor atípico: \(x_i < LI\) ou \(x_i > LS\).

Diagrma de Caixa
Assimetria

Diagrama de Caixa

amostra_51 = pd.read_csv("dados/brutos/amostra_51.csv")
fig, ax = plt.subplots(figsize = (10, 5))
sns.boxplot(data=amostra_51, y='nu_nota_mt', ax=ax)
ax.set_ylabel('Nota de matemática')
plt.show()

amostra_51 = pd.read_csv("dados/brutos/amostra_51.csv")
fig, ax = plt.subplots(figsize = (10, 5))
sns.boxplot(data=amostra_51, x='in_treineiro', y='nu_nota_mt', ax=ax)
ax.set_ylabel('Nota de matemática')
plt.show()

Diagrama de Caixa

  1. Construa um diagrama para a variável nota de matemática (nu_nota_mt) por raça/cor (tp_cor_raca).
  2. Construa um diagrama para a variável nota de português (nu_nota_lc) por raça/cor (tp_cor_raca).
  3. Construa um diagrama para a variável nota de matemática (nu_nota_mt) por gênero (tp_sexo).
  4. Construa um diagrama para a variável nota de português (nu_nota_lc) por gênero (tp_sexo).

Associação entre Duas Variáveis

Associação entre variáveis quantitativas

Ideia

  • Cada observação é um ponto do plano catersiano: \((x_i, y_i)\).
  • Olhar tendência linear da nuvem de pontos.

Gráfico de dispersão

Figura 4: Associação entre duas variáveis quantitativas.

Gráfico de dispersão

  • Dados de flores de iris: iris.xlsx.
  • Existe associação entre o comprimento de pétala e o comprimento de sépala?

df_iris = pd.read_excel("dados/brutos/iris.xlsx")
fig, ax = plt.subplots()
sns.scatterplot(data=df_iris, x='comprimento_sepala', y='comprimento_petala', hue='especies', alpha=0.5, ax=ax)
ax.set_xlabel('Comprimento de Sépala')
ax.set_ylabel('Comprimento de Pétala')
plt.legend(title='Espécies')
plt.show()
Figura 5: Gráfico de dispersão entre as variáveis quantitativas comprimento_sepala e comprimento_petala.

Gráfico de dispersão
Exercício

Para uma amostra ENEM 2023 (cada pessoa tem sua cidade), construa o gráfico de dispersão entre as variáveis quantitativas nu_nota_mt e nu_nota_cn.

Inclua alpha = 0.1 incluir opacidade no gráfico de dispersão. Isso ajuda quando temos amostra de tamanho médio e grande.

Coeficiente de correlação linear de Pearson

.corr: calcula coeficiente de correlação linear de Pearson (\(r\)) entre duas variáveis.

  • \(-1 \leq r \leq 1\)
  • Associação positiva \(\iff r > 0\)
  • Associação negativa \(\iff r < 0\)
  • Associação nula \(\iff r \approx 0\)
df_iris = pd.read_excel("dados/brutos/iris.xlsx")
correlacao = df_iris.corr(numeric_only=True)
correlacao
comprimento_sepala largura_sepala comprimento_petala largura_petala
comprimento_sepala 1.000000 -0.117570 0.871754 0.817941
largura_sepala -0.117570 1.000000 -0.428440 -0.366126
comprimento_petala 0.871754 -0.428440 1.000000 0.962865
largura_petala 0.817941 -0.366126 0.962865 1.000000

Coeficiente de correlação linear de Pearson

sns.heatmap(correlacao, annot=True, cmap='bwr', vmin=-1, vmax=1, fmt='.1f')
plt.show()
Figura 6: Mapa de calor para o coeficiente de correlação linear de Pearson.

Coeficiente de correlação linear de Pearson
Exercício

  1. Calcule o coeficiente de correlação linear de Pearson dois-a-dois para as variáveis nota de matemática (nu_nota_mt), nota de português (nu_nota_lc), nota de ciências naturais (nu_nota_cn) e nota de ciências humanas (nu_nota_ch).
  2. Construa um mapa de calor com o resultado.