02 de maio de 2019
Tempo gasto nas atividades de Data Science. Fonte: https://www.forbes.com/sites/gilpress/2016/03/23/data-preparation-most-time-consuming-least-enjoyable-data-science-task-survey-says.
Quão enfadonhas são as atividades em Data Science. Fonte: https://www.forbes.com/sites/gilpress/2016/03/23/data-preparation-most-time-consuming-least-enjoyable-data-science-task-survey-says.
data.frames do R.# Importa a Numpy. import numpy as np # Consulta a versão e caminho para arquivos. print(np.__version__)
1.16.3
print(np.__path__) # np.__spec__ # np.__doc__
['/home/walmes/anaconda3/lib/python3.7/site-packages/numpy']
# Conteúdo carregado. dir(np)
from timeit import default_timer as tmr l = list(range(100000000)) v = np.array(l) i = tmr(); sum(l); e = tmr(); a = e - i; a i = tmr(); v.sum(); e = tmr(); b = e - i; b a/b u = 999 i = tmr(); y = [x * u for x in l]; e = tmr(); a = e - i; a i = tmr(); f = v * u; e = tmr(); b = e - i; b a/b u = 100000 i = tmr(); f = [x for x in l if x > u]; e = tmr(); a = e - i; a i = tmr(); f = v[v > u]; e = tmr(); b = e - i; b a/b
# Soma. ---------------------------------
>>> i = tmr(); sum(l); e = tmr(); a = e - i; a
0.5613289720001831
>>> i = tmr(); v.sum(); e = tmr(); b = e - i; b
0.06923460899997735
>>> a/b
8.107635474627532
# Multiplicação. ------------------------
>>> u = 999
>>> i = tmr(); y = [x * u for x in l]; e = tmr(); a = e - i; a
4.931227970000009
>>> i = tmr(); f = v * u; e = tmr(); b = e - i; b
0.26028217999987646
>>> a/b
18.94569950967196
# Teste lógico. -------------------------
>>> u = 100000
>>> i = tmr(); f = [x for x in l if x > u]; e = tmr(); a = e - i; a
3.547209543000008
>>> i = tmr(); f = v[v > u]; e = tmr(); b = e - i; b
0.6467253729999811
>>> a/b
5.484877648367929
# Um array unidimensional. A = np.array([4, 7, 5, 1, 9, 7, 4, 0]); A # Modifica as dimensões para redispor o conteúdo. A.shape = (2, 4); A # Um array tridimensional. A.shape = (2, 2, 2); A
# Vetor de 0. np.zeros(shape = 4) # Vetor de 1. np.ones(shape = 4) # Vetor vazio (nan). np.empty(shape = 4) # Vetor de algo qualquer. np.full(shape = 4, fill_value = 99)
# Sequências regulares. np.arange(start = 0, stop = 12, step = 2) np.linspace(start = 0, stop = 12, num = 7) np.logspace(start = -3, stop = 3, num = 7, base = 2) np.geomspace(start = 2**(-3), stop = 2**3, num = 7)
# Repetições. np.repeat(a = np.array([1, 2, 3]), repeats = 2) np.repeat(a = np.array([[1, 2], [3, 4]]), repeats = 2, axis = 0) np.repeat(a = np.array([[1, 2], [3, 4]]), repeats = 2, axis = 1) np.repeat(a = np.array([[1, 2], [3, 4]]), repeats = [2, 1], axis = 0)
# Isso pode ser obtido com soma direta ou Kronecker. np.tile(A = [1, 2, 3], reps = 2) np.tile(A = [1, 2, 3], reps = [3, 2]) np.tile(A = np.array([[1, 2], [3, 4]]), reps = [3, 2])
# Números da distribuição uniforme contínua. np.random.random(size = 3) np.random.uniform(low = 0, high = 1, size = 4) # Números da distribuição uniforme discreta. np.random.randint(low = 0, high = 10, size = 20) # Amostragem de um vetor de valores. np.random.choice(a = [100, 200, 300], size = 7, replace = True) # Números da distribuição normal. np.random.normal(loc = 0, scale = 1, size = 4)
# Arrays multimensionais da uniforme contínua e normal padrão. np.random.rand(3, 4) np.random.randn(3, 4)
# Uma sequência regular. A = np.linspace(start = 100, stop = 110, num = 11) A # Fatiamentos. A[0:2] # Do 0 até 1 inclusive. A[:2] # Idem. A[2:] # Do 2 até o final. A[-2:] # Do 2 de trás para frente até o final. A[::2] # Do começo ao final com passo 2. # Conjuntos. A[[1, 5, 9]] # Na posição 1, 5 e 9. A[[1, -5, 9]] # Nas posição 1, 5 vindo do final e 9.
A = np.random.rand(3, 4) A A[0, :] # Linha 0 e todas as colunas. A[0:2, :] # Linha 0 e 1 e todas as colunas. A[:, 0:3] # Todas as linhas e colunas até 2. A[0:2, 0:3] # Junção das anteriores.
A = np.random.randint(low = 1, high = 5, size = 20) A[A > 3] # Maior. A[A >= 3] # Maior ou igual. A[A < 3] # Menor. A[A <= 3] # Menor ou igual A[A == 3] # Igual A[A != 3] # Diferente.
# São as versões vetoriais de `and`, `or` e `not`. A[(A > 8) & (A < 12)] # Operador AND. A[(A < 8) | (A > 12)] # Operador OR. A[~(A == 3)] # Operador NOT.
A = np.random.rand(3, 4) B = np.random.rand(4, 5) C = np.random.rand(3, 3) D = np.random.rand(4, 4)
# Operações elemento a elemento (elementwise). A + A C - C D * D D / D
# Produto matricial. A.dot(B) C.dot(A) A.T # Transposta. np.diag(C) # Diagonal. np.linalg.inv(C) # Inversa. np.linalg.det(C) # Determinante.
Operações de broadcasting da Numpy. Fonte: https://scipy-lectures.org/intro/numpy/operations.html.
A = np.random.normal(loc = 10, scale = 1.5, size = 50) [A.sum(), A.mean(), A.var(), A.std(), A.max(), A.min()]
np.mean(a = A) np.median(a = A) np.quantile(a = A, q = [0.25, 0.75])
B = np.random.rand(3, 4) np.mean(a = B) np.mean(a = B, axis = 0) np.mean(a = B, axis = 1)
data.table do R e empata com o tidyverse.import pandas as pd print(pd.__version__)
0.24.2
print(pd.__path__)
['/home/walmes/anaconda3/lib/python3.7/site-packages/pandas']
dir(pd)
Categorical, CategoricalDtype, CategoricalIndex, DataFrame, DateOffset, DatetimeIndex, DatetimeTZDtype, ExcelFile, ExcelWriter, Float64Index, Grouper, HDFStore, Index, IndexSlice, ..., api, array, arrays, bdate_range, compat, concat, core, crosstab, cut, date_range, datetime, describe_option, errors, eval, factorize, ..., to_datetime, to_msgpack, to_numeric, to_pickle, to_timedelta, tseries, unique, util, value_counts, wide_to_long
read_.# Lista as funções que possuem `read_` no nome. d = [d for d in dir(pd) if "read_" in d] d
read_clipboard, read_csv, read_excel, read_feather, read_fwf, read_gbq, read_hdf, read_html, read_json, read_msgpack, read_parquet, read_pickle, read_sas, read_sql, read_sql_query, read_sql_table, read_stata, read_table
# `pd.read_table()` é a função de leitura mais genérica. args = pd.read_table.__code__.co_varnames args
filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, squeeze, prefix, mangle_dupe_cols, dtype, engine, ...
# Endereço web do arquivo, mas poderia ser local.
url = "http://leg.ufpr.br/~walmes/data/euro_football_players.txt"
# Importa a tabela de dados.
tb = pd.read_table(filepath_or_buffer = url,
sep = "\t",
comment = "#")
tb.head(n = 6)
country team name pos age ... spg ps aw mom rt 0 Austria Salzburg Sadio Mané M(L) 21.0 ... 2.0 77.0 1.2 3.0 7.98 1 Austria Salzburg Kevin Kampl M(R) 23.0 ... 2.0 83.9 0.3 1.0 7.93 2 Austria Salzburg Alan FW 24.0 ... 4.2 60.8 3.8 2.0 7.91 3 Austria Salzburg André Ramalho D(C) 22.0 ... 0.9 72.3 3.2 1.0 7.67 4 Austria Salzburg Stefan Hierländer M 23.0 ... 0.5 86.3 3.0 NaN 7.59 5 Austria Salzburg Christoph Leitgeb M(C) 28.0 ... 1.6 79.4 0.5 NaN 7.55 [6 rows x 17 columns]
type() retorna a classe do objeto.dir() exibe o conteúdo e um objeto que, no caso de DataFrame, mistura atributos, métodos e variáveis da tabela.see.see() permite aplicação de filtros para exibir conteúdo selecionado..index e .columnstype(tb) # Classe. dir(tb) # Conteúdo.
# Principais atributos. tb.shape tb.index tb.columns
tb.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 1528 entries, 0 to 1527 Data columns (total 17 columns): country 1528 non-null object team 1528 non-null object name 1528 non-null object pos 1528 non-null object age 1524 non-null float64 cm 1444 non-null float64 kg 1417 non-null float64 apps 1326 non-null object goal 412 non-null float64 ass 362 non-null float64 yel 729 non-null float64 red 95 non-null float64 spg 1025 non-null float64 ps 1318 non-null float64 aw 1120 non-null float64 mom 277 non-null float64 rt 1326 non-null float64 dtypes: float64(12), object(5) memory usage: 203.0+ KB None
import see # Exibe todo conteúdo. dot = see.see(tb) dot
.*, [], in, +, +=, -, -=, *, *=, @, /, /=, //, //=, %, %=, **, **=, &, &=, ^, ^=, |, |=, +obj, -obj, ~, <, <=, ==, !=, >, >=, abs(), bool(), dir(), hash(), help(), iter(), len(), repr(), round(), str(), unicode(), .T, .abs(), .add(), .add_prefix(), .add_suffix(), .age, .agg(), .aggregate(), .align(), .all(), .any(), .append(), .apply(), .applymap(), .apps, .as_matrix(), .asfreq(), .asof(), .ass, .assign(), .astype(), .at(), .at_time(), .aw, .axes, .between_time(), ...
# Exibe apenas o que termina com () -> funções.
dot.filter('/()$/')
# Exibe apenas o que NÃO termina com `()` -> atributos e operadores.
dot.filter('/[^(][^)]$/')
Uma tabela com dados fictícios.
# Cria um DataFrame a partir de um dicionário. O dicionário é de
# colunas: um dicionário de arrays.
df1 = pd.DataFrame({
"matricula": [256, 487, 965, 125, 458, 874, 963],
"nome": ["João", "Vanessa", "Tiago", "Luana", "Gisele",
"Pedro", "André"],
"curso": ["Mat", "Mat", "Est", "Est", "Est", "Mat", "Est"],
"prova1": [80, 75, 95, 70, 45, 55, 30],
"prova2": [90, 75, 80, 85, 50, 75, None],
"prova3": [80, 75, 75, 50, None, 90, 30],
"faltas": [4, 4, 0, 8, 16, 0, 20]},
index = list(range(1, 8)))
df2 = pd.DataFrame({
"matricula": [505, 658, 713],
"nome": ["Bia", "Carlos", "Cris"],
"curso": ["Eng", "Eng", "Eng"],
"prova1": [65, 75, 75],
"prova2": [85, 80, 90],
"faltas": [0, 0, 2]},
index = list(range(1, 4)))
# Cria um DataFrame a partir de um array de dicionários. Informação
# organizada por tupla ou registro.
df_extra = pd.DataFrame([
{"mat.": 256, "nome": 'João' , "idade": 18, "bolsista": "S"},
{"mat.": 965, "nome": 'Tiago' , "idade": 18, "bolsista": "N"},
{"mat.": 285, "nome": 'Tiago' , "idade": 22, "bolsista": "N"},
{"mat.": 125, "nome": 'Luana' , "idade": 21, "bolsista": "S"},
{"mat.": 874, "nome": 'Pedro' , "idade": 19, "bolsista": "N"},
{"mat.": 321, "nome": 'Mia' , "idade": 18, "bolsista": "N"},
{"mat.": 669, "nome": 'Luana' , "idade": 19, "bolsista": "S"},
{"mat.": 967, "nome": 'André' , "idade": 20, "bolsista": "N"},
])
Ordenação dos registros de uma tabela.
df1.sort_values(by = "matricula", ascending = True)
matricula nome curso prova1 prova2 prova3 faltas 4 125 Luana Est 70 85.0 50.0 8 1 256 João Mat 80 90.0 80.0 4 5 458 Gisele Est 45 50.0 NaN 16 2 487 Vanessa Mat 75 75.0 75.0 4 6 874 Pedro Mat 55 75.0 90.0 0 7 963 André Est 30 NaN 30.0 20 3 965 Tiago Est 95 80.0 75.0 0
df1.sort_values(by = ["curso", "prova1"],
ascending = [True, True])
matricula nome curso prova1 prova2 prova3 faltas 7 963 André Est 30 NaN 30.0 20 5 458 Gisele Est 45 50.0 NaN 16 4 125 Luana Est 70 85.0 50.0 8 3 965 Tiago Est 95 80.0 75.0 0 6 874 Pedro Mat 55 75.0 90.0 0 2 487 Vanessa Mat 75 75.0 75.0 4 1 256 João Mat 80 90.0 80.0 4
df1.sort_values(by = ["matricula"], inplace = True)
# Nome dos índices de coluna (axis = 1). df1.columns df2.columns # Nome dos índices de linha (axis = 0). df1.index df2.index
# Número de linhas e colunas. df1.shape df2.shape # Número de cédulas. df1.size df2.size
# Seleção das variáveis. df1["nome"] df1[["nome", "prova1", "prova2", "prova3"]]
# Usando `.loc`. df1.loc[:, ["nome", "prova1", "prova2", "prova3"]]
# Usando `.iloc`. df1.iloc[:, :3] df1.iloc[:, -3:] df1.iloc[:, [1, 4]] df1.iloc[:, range(0, 3)]
# Apenas as pares. df1.iloc[:, ::2]
# Concatenação de listas vindas de intervalos. df1.iloc[:, list(range(0, 2)) + list(range(3, 4))]
# Compreensão de lista. v = ["prova1", "prova2", "prova3"] sel = [i for i in df1.columns if not i in v] df1.loc[:, sel] # Seleção. df1.loc[:, ~df1.columns.isin(v)] # Negação (`~`).
# Apenas as de tipo numérico (`float64`). type(df1.dtypes) sel = df1.dtypes == "int64" df1.loc[:, sel]
# Seleção de variáveis por padrão de caracteres (regex).
df1.filter(regex = "^prova") # Começa com "prova".
df1.filter(regex = "\d$") # Termina com número.
df1.filter(regex = "^.{6}$") # Palavra tem 6 algarismos.
# Seleção por posição (só vale slicing, i.e. criados com `:`). df1[:1] df1[-2:] df1[0:4:2] df1[slice(0, 4, 2)]
# Seleção por posição mais geral. df1.iloc[0:2, ] df1.iloc[-2:, ] df1.iloc[range(0, 2), ] df1.iloc[list(range(0, 2)) + list(range(3, 4)), ]
# Convertendo uma coluna para índice dos registros.
df1.set_index("nome", inplace = True)
df1.index
# Seleciona pelo nome dos índices. df1.loc[["Aline", "Vanessa"], :]
# Restaura a indexão. df1.reset_index(inplace = True) df1.index
# Vetor aleatório de valores lógicos.
i = np.random.choice([True, False], size = df1.shape[0],
replace = True, p = [0.4, 0.6])
# Mantém posições que aparecem o True.
df1[i]
# Só permite o uso de escalares. df1.at[3, "nome"] # Com índices rotulados. df1.iat[3, 0] # Com posição.
Filtro dos registros de uma tabela.
# Usando regras lógicas (máscaras lógicas). df1[df1.curso == "Est"] df1[df1.faltas == 0] df1[df1.faltas != 0] df1[df1.nome.isin(["Aline", "Vanessa"])]
df1[(df1.prova1 >= 7) & (df1.prova2 >= 7)] df1[(df1.prova1 + df1.prova2 + df1.prova3)/3 >= 7]
# Lista dos aprovados e reprovados em cálculo.
mask = ((df1.prova1 + df1.prova2 + df1.prova3) >= 21) &\
(df1.faltas < 15)
df1[mask] # Não reprovados (aprovados e exame).
df1[~mask] # Os reprovados (`~` é o operador `not` vetorial).
df1.query("prova1 >= 6")
df1.query("prova1 >= 6 & prova2 >= 6")
df1.query("(prova1 + prova2)/2 >= 6")
df1.query("(prova1 + prova2)/2 >= 6 & faltas < 2")
# Seleção de variáveis por padrão de nome.
df1.filter(regex = "^prova") # Começa com "prova".
df1.filter(regex = "\d$") # Termina com número.
df1.filter(regex = "^.{6}$") # Palavra tem 6 algarismos.
Formas de renomear as colunas de uma tabela.
# Renomeia índices de coluna (variáveis).
df1.rename(columns = {"matricula": "mat.", "faltas": "fl"})
# Renomeia índices de linhas (index).
df1.rename(index = {0: "10", 1: "20"})
# Usando métodos para strings. Deixa caixa alta, capitaliza e trunca.
df1.rename(mapper = str.upper, axis = "columns")
df1.rename(mapper = str.capitalize, axis = "columns")
df1.rename(mapper = lambda x: x[:3] + x[-1:], axis = "columns")
df1.rename(mapper = lambda x: x.replace("prova", "p"), axis = "columns")
# Usando expressão regular (regex).
import re
# Separa o número do texto com um underline.
df1.rename(columns = lambda x: re.sub(pattern = "^(.*)(\d)$",
repl = "\\1_\\2",
string = x))
As operações podem modificar a tabela com a:
As operações de criação/transformação podem ser:
int \(\rightarrow\) str.As transformações podem ser:
Criação e deleção de variáveis em uma tabela.
# Adiciona a coluna com a média.
df1["media"] = (df1.prova1 + df1.prova2 + df1.prova3)/3
# Outra forma de fazer.
df1["media"] = df1.loc[:, ["prova1", "prova2", "prova3"]].\
transform(sum, axis = 1)/3
df1["media"] = df1.media.round(decimals = 2)
df1
# Outra forma de fazer usando função anônima. df1.apply(func = lambda r: (r.prova1 + r.prova2 + r.prova3)/3, axis = 1)
# Transformações com funções de uma variável. df1.faltas.transform(np.sqrt) df1.faltas.transform([np.sqrt, np.log]) # Funções Numpy. df1.faltas.transform(["sqrt", "log"]) # Métodos Pandas. df1.faltas.transform(lambda x: np.power(x, 2))
# Funções aplicadas em várias variáveis df1.loc[:, ["prova1", "prova2"]].transform([np.sqrt, np.log]) df1.loc[:, ["prova1", "prova2"]].apply([np.sqrt, np.log])
# Intervalos para corte e rótulos.
inter = [0, 4, 7, np.inf]
condi = ["reprovado", "exame", "aprovado"]
# Cria a variável que é a condição.
df1["condicao"] = pd.cut(x = df1["media"],
bins = inter,
labels = condi,
right = False,
include_lowest = True)
df1
df1.matricula.transform(str) df1.matricula.transform(float) df1.matricula.astype(str) df1.matricula.astype(float)
# Máscara lógica.
df1.prova2.isnull()
df1.prova2.notnull()
# Troca NaN por 0.
df1.loc[:, ["prova1", "prova2", "prova3"]].fillna(0)
# Troca o NaN por 0 permanente.
df1.fillna({"prova1": 0, "prova2": 0, "prova3": 0},
inplace = True)
df1
df1["media"] = (df1.prova1 + df1.prova2 + df1.prova3)/3 df1 del df1["media"] del df1["condicao"] df1
O Pandas tem recursos para trabalhar com variáveis de tipo especial. Neste tutorial elas não serão abordadas. Consulte a documentação disponível.
Modificação da disposição com empilhamento.
Modificação da disposição com desempilhamento.
# Use um index apropriado.
df1.set_index("nome", inplace = True)
df1
# As funções stack() e unstack().
df1_s = df1.loc[:, ["prova1", "prova2", "prova3"]].stack()
df1_s
df1_s.index
df1_u = df1_s.unstack()
df1_u
df1_u.index
NaN são removidos.df1_s é de classe Series com index multinível.df1_u é de classe DataFrame.# As funções melt() e pivot().
df1.reset_index(inplace = True)
df1_m = df1.melt(id_vars = ["nome", "curso"],
value_vars = ["prova1", "prova2", "prova3"],
var_name = "exame",
value_name = "nota")
df1_m
df1_p = df1_m.pivot(index = "nome",
columns = "exame",
values = "nota").reset_index()
df1_p.columns.name = None
df1_p
df1_m e df1_p são de classe DataFrame.NaN são mantidos..pivot() só permite uma variável em index =.Cálculo de medidas resumo.
# Retornam um valor. [df1.prova1.sum(), df1.prova1.mean(), df1.prova1.min(), df1.prova1.max(), df1.prova1.median(), df1.prova1.count(), # Valores não nulos. len(df1.prova1)] # Comprimento do vetor.
# Retornam um vetor de valores. df1.prova1.describe() # Várias medidas resumo. df1.prova1.value_counts() # Tabela de frequência. df1.prova1.quantile([0.25, 0.75]) # Percentis.
# Aplicando em várias variáveis. df1.loc[:, ['prova1', 'prova2']].mean() df1.loc[:, ['prova1', 'prova2']].std()
# agg() é um alias para aggregate(). Tanto faz qual usar mas prefira o
# curto.
df1["prova1"].agg(lambda x: 100 * x.std()/x.mean())
# Duas versões do coeficiente de variação.
def cv1(x):
return(100 * np.std(x, ddof = 1)/np.mean(x))
def cv2(x):
return(100 * x.std()/x.mean())
# Funcionam igual.
df1.loc[:, ["prova1", "prova2", "prova3", "faltas"]].agg(cv1)
df1.loc[:, ["prova1", "prova2", "prova3", "faltas"]].agg(cv2)
# As mesmas estatísticas para todas as variáveis.
# ATTENTION: só funciona se for com `cv2`.
df1.loc[:, ["prova1", "prova2", "prova3", "faltas"]].\
agg([np.min, np.max, np.mean, cv2])
# Estatísticas diferentes para cada variável.
df1.agg({"prova1": ["sum", "mean"],
"prova2": [np.sum, np.mean],
"faltas": ["min", "max"]},
axis = 0)
Agregação de uma tabela.
Agregação de uma tabela.
Agregação de uma tabela.
# Agregações para conforme o curso.
df1.groupby(["curso"]).agg({"prova1": ["mean", "std"],
"prova2": ["mean", "std"],
"prova3": ["mean", "std"],
"faltas": ["mean", "std"]})
v = ["prova1", "prova2", "prova3", "faltas"]
df1.groupby(["curso"])[v].agg(["mean", "std"])
# Empilhar nas provas.
df1_m = pd.melt(frame = df1,
id_vars = ["curso"],
value_vars = ["prova1", "prova2", "prova3"],
var_name = "exame",
value_name = "nota")
df1_m.groupby(["curso", "exame"])["nota"].\
agg(["mean", "std"]).reset_index()
df1_by = df1.groupby("curso")
df1_by
# Propriedades da tabela agrupada.
df1_by.groups
df1_by.groups.keys()
df1_by.get_group("Est")
df1_by.get_group("Est").agg(["count", "mean", "std"])
# Estatísticas por grupo.
df1_by.prova1.count()
df1_by.prova1.mean()
axis é usado para indicar a direção: 0 - linhas, 1 - colunas.NaN são criadas para os índices que não foram especificados..append().Concatenação de duas tabelas.
# Concatena com a tabela dos alunos de Eng.
pd.concat([df1, df2],
axis = 0,
ignore_index = True,
sort = False)
# Ilustrando como fazer para colunas.
pd.concat([df1.iloc[:5, :4],
df1.iloc[2:, 4:]],
axis = 1,
ignore_index = False)
Tipos de junções de tabelas ilustrado com diagramas de Veen.
Junções de tabelas do tipo inclusivas.
df1 = df1.loc[:, ["matricula", "curso", "nome",
"prova1", "prova2", "prova3", "faltas"]]
df_extra.rename(columns = {"mat.": "matricula"},
inplace = True)
# How pode ser: inner, outer, left ou right.
pd.merge(left = df1, right = df_extra,
how = "inner", on = ["nome", "matricula"])
pd.merge(left = df1, right = df_extra,
how = "outer", on = ["nome", "matricula"])
pd.merge(left = df1, right = df_extra,
how = "left", on = ["nome", "matricula"])
pd.merge(left = df1, right = df_extra,
how = "right", on = ["nome", "matricula"])
import matplotlib.pyplot as plt import seaborn as sns
tb["cm"].plot.hist(bins = 20) plt.show()
plt.close() tb["cm"].plot.density(color = "red") plt.show()
plt.close() tb2 = tb[tb.country.isin(["Italy", "England"])] tb2.groupby(["country"])["cm"].plot.density()
plt.legend(); plt.show()
plt.close()
sns.distplot(tb.loc[tb.cm.notnull(), ["cm"]],
hist = True, kde = True, rug = True)
plt.show()
plt.close() sns.barplot(tb2.country, tb2.yel) plt.show()
plt.close() sns.scatterplot(tb2.cm, tb2.kg, hue = tb2.country) plt.show()
plt.close() sns.boxplot(tb2.country, tb2.cm) plt.show()
plt.close() sns.violinplot(tb2.country, tb2.kg) plt.show()
plt.close() sns.pairplot(data = tb2, vars = ["cm", "kg", "age"], hue = "country")
plt.show()
country).team).age) geral dos jogadores.kg) geral dos jogadores.cm).goal).cm).rt).cm).apps > 0).yel), vermelhos (red), gols (goal), e assistências a gol (ass).age) em grupos de 5 anos.Criar as faixa de índice de massa corporal.
BMI < 18.5 : Below normal weight BMI >= 18.5 and < 25 : Normal weight BMI >= 25 and < 30 : Overweight BMI >= 30 and < 35 : Class I Obesity BMI >= 35 and < 40 : Class II Obesity BMI >= 40 : Class III Obesity
bmi.