Capítulo 8.2
Índice
- 1. O que é Ciência de Dados?
- 2. Causalidade e Experimentos
- 3. Progamando em Python
- 4. Tipos de Dados
- 5. Sequências
- 6. Tabelas
- 7. Visualização
- 8. Funções e Tabelas
- 9. Aleatoriedade
- 10. Amostragem e Distribuições Empíricas
- 11. Testando Hipóteses
- 12. Comparando Duas Amostras
- 13. Estimação
- 14. Por que a Média é Importante
- 15. Previsão
from datascience import *
path_data = '../../../assets/data/'
import matplotlib
matplotlib.use('Agg')
%matplotlib inline
import matplotlib.pyplot as plots
plots.style.use('fivethirtyeight')
import numpy as np
Classificando por uma Variável
Os cientistas de dados frequentemente precisam classificar indivíduos em grupos de acordo com características compartilhadas, e então identificar algumas características dos grupos. Por exemplo, no exemplo usando os dados de alturas de Galton, vimos que era útil classificar as famílias de acordo com as alturas médias dos pais e depois encontrar a altura média das crianças em cada grupo.
Esta seção trata da classificação de indivíduos em categorias que não são numéricas. Começamos lembrando o uso básico do group.
Contando o Número em Cada Categoria
O método group com um único argumento conta o número de linhas para cada categoria em uma coluna. O resultado contém uma linha para cada valor único na coluna agrupada.
Aqui está uma pequena tabela de dados sobre cones de sorvete. O método group pode ser usado para listar os sabores distintos e fornecer a contagem de cada sabor.
cones = Table().with_columns(
'Flavor', make_array('strawberry', 'chocolate', 'chocolate', 'strawberry', 'chocolate'),
'Price', make_array(3.55, 4.75, 6.55, 5.25, 5.25)
)
cones
| Flavor | Price |
|---|---|
| strawberry | 3.55 |
| chocolate | 4.75 |
| chocolate | 6.55 |
| strawberry | 5.25 |
| chocolate | 5.25 |
cones.group('Flavor')
| Flavor | count |
|---|---|
| chocolate | 3 |
| strawberry | 2 |
Existem duas categorias distintas, chocolate e morango. A chamada para group cria uma tabela de contagens em cada categoria. A coluna é chamada count por padrão e contém o número de linhas em cada categoria.
Perceba que tudo isso pode ser resolvido apenas a partir da coluna Flavor. A coluna Price não foi usada.
Mas e se quiséssemos o preço total dos cones de cada sabor diferente? Aí é onde entra o segundo argumento do group.
Encontrando uma Característica de Cada Categoria
O segundo argumento opcional do group nomeia a função que será usada para agregar valores em outras colunas para todas aquelas linhas. Por exemplo, sum somará os preços em todas as linhas que correspondem a cada categoria. Esse resultado também contém uma linha para cada valor único na coluna agrupada, mas tem o mesmo número de colunas que a tabela original.
Para encontrar o preço total de cada sabor, chamamos group novamente, com Flavor como primeiro argumento como antes. Mas desta vez há um segundo argumento: o nome da função sum.
cones.group('Flavor', sum)
| Flavor | Price sum |
|---|---|
| chocolate | 16.55 |
| strawberry | 8.8 |
Para criar esta nova tabela, o group calculou a soma das entradas de Price em todas as linhas correspondentes a cada sabor distinto. Os preços nas três linhas de chocolate somam $16.55 (você pode assumir que o preço está sendo medido em dólares). Os preços nas duas linhas de strawberry totalizam $8.80.
O rótulo da coluna recém-criada “sum” é Price sum, que é criado pegando o rótulo da coluna que está sendo somada e acrescentando a palavra sum.
Como o group encontra a sum (soma) de todas as colunas que não são a dos categorias, não há necessidade de especificar que ele deve sum (somar) os preços.
Para entender mais detalhadamente o que o group está fazendo, observe que você poderia ter calculado os preços totais você mesmo, não apenas fazendo cálculos mentais, mas também usando código. Por exemplo, para encontrar o preço total de todos os cones de chocolate, você poderia começar criando uma nova tabela consistindo apenas dos cones de chocolate e, em seguida, acessar a coluna de preços:
cones.where('Flavor', are.equal_to('chocolate')).column('Price')
| Out[4]: | array([4.75, 6.55, 5.25]) |
sum(cones.where('Flavor', are.equal_to('chocolate')).column('Price'))
| Out[5]: | 16.55 |
Isso é o que group está fazendo para cada valor distinto em Flavor.
# Para cada valor distinto em `Flavor, acesse todas as linhas
# e crie um array de `Price`
cones_choc = cones.where('Flavor', are.equal_to('chocolate')).column('Price')
cones_strawb = cones.where('Flavor', are.equal_to('strawberry')).column('Price')
# Exibir os arrays em uma tabela
grouped_cones = Table().with_columns(
'Flavor', make_array('chocolate', 'strawberry'),
'Array of All the Prices', make_array(cones_choc, cones_strawb)
)
# Anexe uma coluna com a soma dos valores `Price` em cada array
price_totals = grouped_cones.with_column(
'Sum of the Array', make_array(sum(cones_choc), sum(cones_strawb))
)
price_totals
| Flavor | Array of All the Prices | Sum of the Array |
|---|---|---|
| chocolate | [4.75 6.55 5.25] | 16.55 |
| strawberry | [3.55 5.25] | 8.8 |
Você pode substituir sum por qualquer outra função que funcione em arrays. Por exemplo, você pode usar max para encontrar o maior preço em cada categoria:
cones.group('Flavor', max)
| Flavor | Price max |
|---|---|
| chocolate | 6.55 |
| strawberry | 5.25 |
Mais uma vez, group cria matrizes de preços em cada categoria Flavor. Mas agora ele encontra o max de cada array:
price_maxes = grouped_cones.with_column(
'Max of the Array', make_array(max(cones_choc), max(cones_strawb))
)
price_maxes
| Flavor | Array of All the Prices | Max of the Array |
|---|---|---|
| chocolate | [4.75 6.55 5.25] | 6.55 |
| strawberry | [3.55 5.25] | 5.25 |
Na verdade, a chamada original para group com apenas um argumento tem o mesmo efeito que usar len como função e depois limpar a tabela.
lengths = grouped_cones.with_column(
'Length of the Array', make_array(len(cones_choc), len(cones_strawb))
)
lengths
| Flavor | Array of All the Prices | Length of the Array |
|---|---|---|
| chocolate | [4.75 6.55 5.25] | 3 |
| strawberry | [3.55 5.25] | 2 |
Exemplo: Salários da NBA
A tabela nba contém dados sobre os jogadores da National Basketball Association de 2015-2016. Já examinamos esses dados anteriormente. Lembre-se de que os salários são medidos em milhões de dólares.
nba1 = Table.read_table(path_data + 'nba_salaries.csv')
nba = nba1.relabeled("'15-'16 SALARY", 'SALARY')
nba
| PLAYER | POSITION | TEAM | SALARY |
|---|---|---|---|
| Paul Millsap | PF | Atlanta Hawks | 18.6717 |
| Al Horford | C | Atlanta Hawks | 12.0 |
| Tiago Splitter | C | Atlanta Hawks | 9.75625 |
| Jeff Teague | PG | Atlanta Hawks | 8.0 |
| Kyle Korver | SG | Atlanta Hawks | 5.74648 |
| Thabo Sefolosha | SF | Atlanta Hawks | 4.0 |
| Mike Scott | PF | Atlanta Hawks | 3.33333 |
| Kent Bazemore | SF | Atlanta Hawks | 2.0 |
| Dennis Schroder | PG | Atlanta Hawks | 1.7634 |
| Tim Hardaway Jr. | SG | Atlanta Hawks | 1.30452 |
1. Quanto dinheiro cada equipe pagou pelos salários de seus jogadores?
As únicas colunas envolvidas são TEAM e SALARY. Temos que agrupar as linhas por TEAM e depois sum (somar) os salários dos grupos.
teams_and_money = nba.select('TEAM', 'SALARY')
teams_and_money.group('TEAM', sum)
| TEAM | SALARY sum |
|---|---|
| Atlanta Hawks | 69.5731 |
| Boston Celtics | 50.2855 |
| Brooklyn Nets | 57.307 |
| Charlotte Hornets | 84.1024 |
| Chicago Bulls | 78.8209 |
| Cleveland Cavaliers | 102.312 |
| Dallas Mavericks | 65.7626 |
| Denver Nuggets | 62.4294 |
| Detroit Pistons | 42.2118 |
| Golden State Warriors | 94.0851 |
2. Quantos jogadores da NBA havia em cada uma das cinco posições?
Temos que classificar por POSITION e contar. Isso pode ser feito com apenas um argumento para agrupar:
nba.group('POSITION')
| POSITION | count |
|---|---|
| C | 69 |
| PF | 85 |
| PG | 85 |
| SF | 82 |
| SG | 96 |
3. Qual foi o salário médio dos jogadores em cada uma das cinco posições?
Desta vez temos que agrupar por POSITION e tirar a média dos salários. Para maior clareza trabalharemos com uma tabela apenas dos cargos e dos salários.
positions_and_money = nba.select('POSITION', 'SALARY')
positions_and_money.group('POSITION', np.mean)
| POSITION | SALARY mean |
|---|---|
| C | 6.08291 |
| PF | 4.95134 |
| PG | 5.16549 |
| SF | 5.53267 |
| SG | 3.9882 |
O Center foi a posição mais bem paga, com uma média de mais de 6 milhões de dólares.
Se não tivéssemos selecionado as duas colunas como nosso primeiro passo, group não tentaria “averiguar” as colunas categóricas em nba. (É impossível calcular a média de duas strings como “Atlanta Hawks” e “Boston Celtics”.) Ele realiza operações aritméticas apenas em colunas numéricas e deixa o resto em branco.
nba.group('POSITION', np.mean)
| POSITION | PLAYER mean | TEAM mean | SALARY mean |
|---|---|---|---|
| C | 6.08291 | ||
| PF | 4.95134 | ||
| PG | 5.16549 | ||
| SF | 5.53267 | ||
| SG | 3.9882 |
| ← Capítulo 8.1 – Aplicando uma Função a uma Coluna | Capítulo 8.3 – Classificação Cruzada → |
