Capítulo 6
Í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
import numpy as np
np.set_printoptions(threshold=50)
path_data = '../../assets/data/'
Tabelas
Tabelas são um tipo fundamental de objeto para representar conjuntos de dados. Uma tabela pode ser vista de duas maneiras:
- uma sequência de colunas nomeadas que descrevem cada aspecto de todas as entradas em um conjunto de dados, ou
- uma sequência de linhas que contêm todas as informações sobre uma única entrada em um conjunto de dados.
Para usar tabelas, importe todo o módulo chamado datascience, um módulo criado para este texto.
from datascience import *
Tabelas vazias podem ser criadas usando a função Table. Uma tabela vazia é útil porque pode ser estendida para conter novas linhas e colunas.
Table()
O método with_columns em uma tabela constrói uma nova tabela com colunas adicionais rotuladas. Cada coluna de uma tabela é um array. Para adicionar uma nova coluna a uma tabela, chame with_columns com um rótulo e um array. (O método with_column pode ser usado com o mesmo efeito.)
Abaixo, começamos cada exemplo com uma tabela vazia que não tem colunas.
Table().with_columns('Number of petals', make_array(8, 34, 5))
| Number of petals |
|---|
| 8 |
| 34 |
| 5 |
Para adicionar duas (ou mais) novas colunas, forneça o rótulo e o array para cada coluna. Todas as colunas devem ter o mesmo comprimento, ou ocorrerá um erro.
Table().with_columns(
'Number of petals', make_array(8, 34, 5),
'Name', make_array('lotus', 'sunflower', 'rose')
)
| Number of petals | Name |
|---|---|
| 8 | lotus |
| 34 | sunflower |
| 5 | rose |
Podemos dar um nome a esta tabela e, em seguida, estender a tabela com outra coluna.
flowers = Table().with_columns(
'Number of petals', make_array(8, 34, 5),
'Name', make_array('lotus', 'sunflower', 'rose')
)
flowers.with_columns(
'Color', make_array('pink', 'yellow', 'red')
)
| Number of petals | Name | Color |
|---|---|---|
| 8 | lotus | pink |
| 34 | sunflower | yellow |
| 5 | rose | red |
O método with_columns cria uma nova tabela cada vez que é chamado, então a tabela original não é afetada. Por exemplo, a tabela flowers ainda tem apenas as duas colunas que tinha quando foi criada.
flowers
| Number of petals | Name |
|---|---|
| 8 | lotus |
| 34 | sunflower |
| 5 | rose |
Criar tabelas dessa maneira envolve muita digitação. Se os dados já tiverem sido inseridos em algum lugar, geralmente é possível usar o Python para lê-los em uma tabela, em vez de digitá-los célula por célula.
Muitas vezes, as tabelas são criadas a partir de arquivos que contêm valores separados por vírgula. Esses arquivos são chamados de arquivos CSV.
Abaixo, usamos o método read_table da Tabela para ler um arquivo CSV que contém alguns dos dados usados por Minard em seu gráfico sobre a campanha russa de Napoleão. Os dados são colocados em uma tabela chamada minard.
minard = Table.read_table(path_data + 'minard.csv')
minard
| Longitude | Latitude | City | Direction | Survivors |
|---|---|---|---|---|
| 32 | 54.8 | Smolensk | Advance | 145000 |
| 33.2 | 54.9 | Dorogobouge | Advance | 140000 |
| 34.4 | 55.5 | Chjat | Advance | 127100 |
| 37.6 | 55.8 | Moscou | Advance | 100000 |
| 34.3 | 55.2 | Wixma | Retreat | 55000 |
| 32 | 54.6 | Smolensk | Retreat | 24000 |
| 30.4 | 54.4 | Orscha | Retreat | 20000 |
| 26.8 | 54.3 | Moiodexno | Retreat | 12000 |
Usaremos esta pequena tabela para demonstrar alguns métodos úteis da Tabela. Em seguida, usaremos esses mesmos métodos e desenvolveremos outros métodos de tabelas com muito maiores e com muito mais dados.
O Tamanho da Tabela
O método num_columns fornece o número de colunas na tabela, e num_rows o número de linhas.
minard.num_columns
| Out[1]: | 5 |
minard.num_rows
| Out[1]: | 8 |
Rótulos de Colunas
O método labels pode ser usado para listar os rótulos de todas as colunas. Com minard, não ganhamos muito com isso, mas pode ser muito útil para tabelas tão grandes que nem todas as colunas são visíveis na tela.
minard.labels
| Out[1]: | (‘Longitude’, ‘Latitude’, ‘City’, ‘Direction’, ‘Survivors’) |
Podemos alterar os rótulos das colunas usando o método relabeled. Isso cria uma nova tabela e deixa minard inalterada.
minard.relabeled('City', 'City Name')
| Longitude | Latitude | City Name | Direction | Survivors |
|---|---|---|---|---|
| 32 | 54.8 | Smolensk | Advance | 145000 |
| 33.2 | 54.9 | Dorogobouge | Advance | 140000 |
| 34.4 | 55.5 | Chjat | Advance | 127100 |
| 37.6 | 55.8 | Moscou | Advance | 100000 |
| 34.3 | 55.2 | Wixma | Retreat | 55000 |
| 32 | 54.6 | Smolensk | Retreat | 24000 |
| 30.4 | 54.4 | Orscha | Retreat | 20000 |
| 26.8 | 54.3 | Moiodexno | Retreat | 12000 |
No entanto, este método não altera a tabela original.
minard
| Longitude | Latitude | City | Direction | Survivors |
|---|---|---|---|---|
| 32 | 54.8 | Smolensk | Advance | 145000 |
| 33.2 | 54.9 | Dorogobouge | Advance | 140000 |
| 34.4 | 55.5 | Chjat | Advance | 127100 |
| 37.6 | 55.8 | Moscou | Advance | 100000 |
| 34.3 | 55.2 | Wixma | Retreat | 55000 |
| 32 | 54.6 | Smolensk | Retreat | 24000 |
| 30.4 | 54.4 | Orscha | Retreat | 20000 |
| 26.8 | 54.3 | Moiodexno | Retreat | 12000 |
Um padrão comum é atribuir o nome original minard à nova tabela, para que todos os usos futuros de minard se refiram à tabela com os rótulos alterados.
minard = minard.relabeled('City', 'City Name')
minard
| Longitude | Latitude | City Name | Direction | Survivors |
|---|---|---|---|---|
| 32 | 54.8 | Smolensk | Advance | 145000 |
| 33.2 | 54.9 | Dorogobouge | Advance | 140000 |
| 34.4 | 55.5 | Chjat | Advance | 127100 |
| 37.6 | 55.8 | Moscou | Advance | 100000 |
| 34.3 | 55.2 | Wixma | Retreat | 55000 |
| 32 | 54.6 | Smolensk | Retreat | 24000 |
| 30.4 | 54.4 | Orscha | Retreat | 20000 |
| 26.8 | 54.3 | Moiodexno | Retreat | 12000 |
Acessando os Dados em um Coluna
Podemos usar o rótulo de uma coluna para acessar a matriz de dados da coluna.
minard.column('Survivors')
| Out[1]: | array([145000, 140000, 127100, 100000, 55000, 24000, 20000, 12000]) |
As 5 colunas são indexadas 0, 1, 2, 3 e 4. A coluna Survivors também pode ser acessada usando seu índice de coluna.
minard.column(4)
| Out[1]: | array([145000, 140000, 127100, 100000, 55000, 24000, 20000, 12000]) |
Os 8 itens na matriz são indexados 0, 1, 2 e assim por diante, até 7. Os itens na coluna podem ser acessados usando item, como acontece com qualquer matriz.
minard.column(4).item(0)
| Out[1]: | 145000 |
minard.column(4).item(5)
| Out[1]: | 24000 |
Trabalhando com os Dados em uma Coluna
Como as colunas são matrizes, podemos usar operações de matriz nelas para descobrir novas informações. Por exemplo, podemos criar uma nova coluna que contenha a porcentagem de todos os sobreviventes em cada cidade depois de Smolensk.
initial = minard.column('Survivors').item(0)
minard = minard.with_columns(
'Percent Surviving', minard.column('Survivors')/initial
)
minard
| Longitude | Latitude | City Name | Direction | Survivors | Percent Surviving |
|---|---|---|---|---|---|
| 32 | 54.8 | Smolensk | Advance | 145000 | 1 |
| 33.2 | 54.9 | Dorogobouge | Advance | 140000 | 0.965517 |
| 34.4 | 55.5 | Chjat | Advance | 127100 | 0.876552 |
| 37.6 | 55.8 | Moscou | Advance | 100000 | 0.689655 |
| 34.3 | 55.2 | Wixma | Retreat | 55000 | 0.37931 |
| 32 | 54.6 | Smolensk | Retreat | 24000 | 0.165517 |
| 30.4 | 54.4 | Orscha | Retreat | 20000 | 0.137931 |
| 26.8 | 54.3 | Moiodexno | Retreat | 12000 | 0.0827586 |
Para fazer com que as proporções nas novas colunas apareçam como porcentagens, podemos usar o método set_format com a opção PercentFormatter. O método set_format aceita objetos Formatter, que existem para datas (DateFormatter), moedas (CurrencyFormatter), números e porcentagens.
minard.set_format('Percent Surviving', PercentFormatter)
| Longitude | Latitude | City Name | Direction | Survivors | Percent Surviving |
|---|---|---|---|---|---|
| 32 | 54.8 | Smolensk | Advance | 145000 | 100.00% |
| 33.2 | 54.9 | Dorogobouge | Advance | 140000 | 96.55% |
| 34.4 | 55.5 | Chjat | Advance | 127100 | 87.66% |
| 37.6 | 55.8 | Moscou | Advance | 100000 | 68.97% |
| 34.3 | 55.2 | Wixma | Retreat | 55000 | 37.93% |
| 32 | 54.6 | Smolensk | Retreat | 24000 | 16.55% |
| 30.4 | 54.4 | Orscha | Retreat | 20000 | 13.79% |
| 26.8 | 54.3 | Moiodexno | Retreat | 12000 | 8.28% |
Escolhendo Conjuntos de Colunas
O método select cria uma nova tabela que contém apenas as colunas especificadas.
minard.select('Longitude', 'Latitude')
| Longitude | Latitude |
|---|---|
| 32 | 54.8 |
| 33.2 | 54.9 |
| 34.4 | 55.5 |
| 37.6 | 55.8 |
| 34.3 | 55.2 |
| 32 | 54.6 |
| 30.4 | 54.4 |
| 26.8 | 54.3 |
A mesma seleção pode ser feita usando índices de coluna em vez de rótulos.
minard.select(0, 1)
| Longitude | Latitude |
|---|---|
| 32 | 54.8 |
| 33.2 | 54.9 |
| 34.4 | 55.5 |
| 37.6 | 55.8 |
| 34.3 | 55.2 |
| 32 | 54.6 |
| 30.4 | 54.4 |
| 26.8 | 54.3 |
O resultado do uso de select é uma nova tabela, mesmo quando você seleciona apenas uma coluna.
minard.select('Survivors')
| Survivors |
|---|
| 145000 |
| 140000 |
| 127100 |
| 100000 |
| 55000 |
| 24000 |
| 20000 |
| 12000 |
Observe que o resultado é uma tabela, diferentemente do resultado de column, que é um array.
minard.column('Survivors')
| Out[1]: | array([145000, 140000, 127100, 100000, 55000, 24000, 20000, 12000]) |
Outra maneira de criar uma nova tabela consistindo em um conjunto de colunas é remover (drop) as colunas que você não deseja.
minard.drop('Longitude', 'Latitude', 'Direction')
| City Name | Survivors | Percent Surviving |
|---|---|---|
| Smolensk | 145000 | 100.00% |
| Dorogobouge | 140000 | 96.55% |
| Chjat | 127100 | 87.66% |
| Moscou | 100000 | 68.97% |
| Wixma | 55000 | 37.93% |
| Smolensk | 24000 | 16.55% |
| Orscha | 20000 | 13.79% |
| Moiodexno | 12000 | 8.28% |
Tanto select quanto drop não alteram a tabela original. Em vez disso, eles criam novas tabelas menores que compartilham os mesmos dados. O fato de a tabela original ser preservada é útil! Você pode gerar várias tabelas diferentes que consideram apenas determinadas colunas sem se preocupar que uma análise afetará a outra.
minard
| Longitude | Latitude | City Name | Direction | Survivors | Percent Surviving |
|---|---|---|---|---|---|
| 32 | 54.8 | Smolensk | Advance | 145000 | 100.00% |
| 33.2 | 54.9 | Dorogobouge | Advance | 140000 | 96.55% |
| 34.4 | 55.5 | Chjat | Advance | 127100 | 87.66% |
| 37.6 | 55.8 | Moscou | Advance | 100000 | 68.97% |
| 34.3 | 55.2 | Wixma | Retreat | 55000 | 37.93% |
| 32 | 54.6 | Smolensk | Retreat | 24000 | 16.55% |
| 30.4 | 54.4 | Orscha | Retreat | 20000 | 13.79% |
| 26.8 | 54.3 | Moiodexno | Retreat | 12000 | 8.28% |
Todos os métodos que usamos acima podem ser aplicados a qualquer tabela.
| ← Capítulo 5.3 – Mais sobre Arrays | Capítulo 6.1 – Ordenando Linhas → |
