15 - Organizar Dados15 - Organizar Dados15 - Organizar...

Post on 08-Jul-2020

28 views 0 download

Transcript of 15 - Organizar Dados15 - Organizar Dados15 - Organizar...

ICE-BICE-BICE-BICE-BICE-BICE-BICE-BICE-BICE-B

15 - Organizar Dados15 - Organizar Dados15 - Organizar Dados15 - Organizar Dados15 - Organizar Dados15 - Organizar Dados15 - Organizar Dados15 - Organizar Dados15 - Organizar Dados

Ludwig Krippahl

1

Organizar DadosOrganizar DadosOrganizar DadosOrganizar DadosOrganizar DadosOrganizar DadosOrganizar DadosOrganizar DadosOrganizar Dados

Resumo■ Organização de dados:• Ficheiros, listas, matrizes e dicionários

■ Ler e representar dados (gráficos)■ Dicionário como relação de atributos■ Vector de dicionários como uma tabela■ Selecção de campos e cruzamento de tabelas

2

Tabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas Numéricas

3

Tabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas Numéricas

Exemplo: temperaturas por país■ PRT.csv ■ DEU.csvyear,data

1901,14.236396789550781

1902,14.387377738952637

1903,14.560417175292969

1904,14.721814155578613

1905,14.297182083129883

...

year,data

1901,7.781550407409668

1902,7.262444972991943

1903,8.382242202758789

1904,8.436717987060547

1905,8.02903938293457

...

■ Podemos obter estes valores do World Bank neste URL:http://climatedataapi.worldbank.org/climateweb/rest/v1/country/cru/tas/year/[COD].csv

■ Ou então podemos tê-los já em ficheiros no disco.■ Vamos considerar ambas as possibilidades:• Carregar um lote de países para um dicionário de tabelas• De ficheiro ou do servidor

4

Tabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas Numéricas

Exemplo: temperaturas por país■ Decompor o problema:• Um país, uma tabela, de ficheiro ou servidor• Vários países, um dicionário, de ficheiro ou servidor

def load_temperatures(file_name, online=False): """Return numpy array with years and temperatures for given name (code.csv) If online load from server""" def load_countries(codes, online=False): """Return dictionary with one table per country code Loads tables from file, or server if online is True"""

5

Tabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas Numéricas

import numpy as np from requests import get BASE_URL = 'http://climatedataapi.worldbank.org/'+\ 'climateweb/rest/v1/country/cru/tas/year/' def load_temperatures(file_name, online=False): """Return numpy array with years and temperatures for given name (code.csv) If online load from server""" if online: response = get(BASE_URL+file_name) lines = response.text.strip().split('\n') else: lines = open(file_name).readlines() table = [] for line in lines[1:]: year, temp = line.split(',') table.append( (int(year),float(temp))) return np.array(table)

6

Tabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas Numéricas

def load_temperatures(file_name, online=False): """Return numpy array with years and temperatures for given name (code.csv) If online load from server""" ...

In : load_temperatures('PRT.csv',True) Out: array([[1901. , 14.23639679], [1902. , 14.38737774], [1903. , 14.56041718], [1904. , 14.72181416],

■ Se temos o ficheiro PRT.csv

In : load_temperatures('PRT.csv') Out: array([[1901. , 14.23639679], [1902. , 14.38737774], [1903. , 14.56041718], [1904. , 14.72181416],

7

Tabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas Numéricas

def load_countries(codes, online=False): """Return dictionary with one table per country code Loads tables from file, or server if online is True""" countries = {} for code in codes: countries[code] = load_temperatures(code+'.csv', online) return countries

In : countries = load_countries(['PRT','ESP','FRA'],True) Out: {'PRT': array([[1901. , 14.23639679],...]), 'ESP': array([[1901. , 12.61713982],...]), 'FRA': array([[1901. , 9.74886513],...])}

■ Ou omitindo (ou False) o segundo argumento se tivermos osficheiros na pasta.

8

Tabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas Numéricas

■ Já temos os dados organizados, vamos fazer o gráfico■ Generalizar:• Podemos escolher o intervalo de anos• Podemos escolher os países (daqueles que há no dicionário)

def plot_years(first,last,codes,countries): """from countries dictionary, plot countries given in codes in specified interval""" plt.figure(figsize=(10,5)) for code in codes: table = countries[code] years = np.logical_and(table[:,0]>=first, table[:,0]<=last) data = table[years,:] plt.plot(data[:,0],data[:,1],label=code) plt.legend() plt.show()

In : plot_years(1960,2000,['PRT','ESP','FRA'],countries)

9

Tabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas Numéricas

■ Já temos os dados organizados, vamos fazer o gráfico

In : plot_years(1960,2000,['PRT','ESP','FRA'],countries)

10

Tabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas NuméricasTabelas Numéricas

Exemplo: temperaturas por país■ Funções para ler os dados e organizá-los• Dicionário com código do país e matriz

■ Depois processamos os dados organizados• Exemplo: função para fazer gráfico a partir do dicionário

Esquema genérico:■ Guardar os dados num formato prático para processamento■ Processar os dados nesse formato

11

Tabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas Mistas

12

Tabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas Mistas

Exemplo (antiquado): Clube de vídeofilmes.tsv: id_filme, tipo, titulo, classificacao

101 Sexto Sentido suspense drama maiores de 12

102 Regresso ao Futuro comedia aventura maiores de 6

103 Monstros e Cia. animacao maiores de 4

...

clientes.tsv:id_cliente, nome, morada, c_credito

101 Artur Meireles Rua da Paz, 20 123412341234123401

102 Joana Fonseca Rua da Guerra, 123 4123412341234123402

103 Artur Lopes da Silva Av.Liberdade, 202 123412341234123403

...

alugueres.tsv:id_aluguer, id_filme, id_cliente, data_aluguer, data_entrega

1001 109 102 05/10/14 05/11/14

1002 106 101 05/12/14 NULL

1003 102 107 05/13/14 NULL

1004 104 102 05/11/14 05/12/14

13

Tabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas Mistas

Exemplo (antiquado): Clube de vídeo■ Cada tabela tem campos diferentes• Filmes: id_filme, tipo, titulo, classificacao• Clientes: id_cliente, nome, morada, c_credito

• Alugueres: id_aluguer, id_filme, id_cliente, data_aluguer, data_entrega

■ Relações 1 para 1:• Não é prático guardar relações de um para vários na mesma tabela

• nome, morada e cartão de crédito funciona• nome de cada cliente e filmes alugados já não é prático

■ Para fazer "perguntas" temos de cruzar tabelas• Nome dos filmes alugados e data de entrega• Nome da pessoa e filme que alugou• ...

14

Tabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas Mistas

Exemplo (antiquado): Clube de vídeo■ Ler as tabelas para um dicionário• Cada tabela é uma lista de dicionários com os campos e valores• A nossa "base de dados" será um dicionário com todas as tabelas• Vamos fazer uma funçao genérica, que sirva para qualquer tabela

■ Processar os dados• Juntar duas tabelas por um campo (e.g. identificador)• Seleccionar colunas da tabela (os campos dos registos)• Mostrar uma tabela (print)

15

Tabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas Mistas

■ Ler uma tabela para uma lista de dicionários

def load_table(file_name,fields): "Read file into list of dictionaries with given fields" lines = open(file_name).readlines() table = [] for line in lines: cells = line.strip().split('\t') record = {} for ix in range(len(fields)): record[fields[ix]]=cells[ix] table.append( record ) return table

In : load_table('filmes.tsv',['id_filme','titulo','tipo','classificacao']) Out: [{'classificacao': 'maiores de 12','id_filme': '101', 'tipo': 'suspense drama', 'titulo': 'Sexto Sentido'}, {'classificacao': 'maiores de 6','id_filme': '102', 'tipo': 'comedia aventura', 'titulo': 'Regresso ao Futuro'}, ...]

16

Tabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas Mistas

■ Ler uma tabela para uma lista de dicionários

def load_table(file_name,fields): "Read file into list of dictionaries with given fields" lines = open(file_name).readlines() table = [] for line in lines: cells = line.strip().split('\t') record = {} for ix in range(len(fields)): record[fields[ix]]=cells[ix] table.append( record ) return table

In : load_table('clientes.tsv',['id_cliente','nome','morada','c_credito']) Out: [{'c_credito': '123412341234123401', 'id_cliente': '101', 'morada': 'Rua da Paz, 20', 'nome': 'Artur Meireles'}, {'c_credito': '123412341234123402', 'id_cliente': '102', 'morada': 'Rua da Guerra, 1234', 'nome': 'Joana Fonseca '}, ...]

17

Tabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas Mistas

■ Ler uma tabela para uma lista de dicionários

def load_table(file_name,fields): "Read file into list of dictionaries with given fields" lines = open(file_name).readlines() table = [] for line in lines: cells = line.strip().split('\t') record = {} for ix in range(len(fields)): record[fields[ix]]=cells[ix] table.append( record ) return table

In : load_table('alugueres.tsv',['id_aluguer', 'id_filme', 'id_cliente', 'data_aluguer', 'data_entrega']) Out: [{'id_aluguer': '1001', 'id_filme': '109', 'id_cliente': '102', 'data_aluguer': '05/10/14','data_entrega': '05/11/14'}, {'id_aluguer': '1002', 'id_filme': '106', 'id_cliente': '101', 'data_aluguer': '05/12/14', 'data_entrega': 'NULL'},... ]

18

Tabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas Mistas

■ Ler as tabelas para um dicionário de tabelas ("base de dados")• A partir de um dicionário com o esquema das tabelas

def load_db(table_defs): """Reads all tables into a dictionary Argument table_defs is dictionary with table name and dictionary with file name and fields """ db = {} for table_name in table_defs: table = table_defs[table_name] db[table_name] = load_table(table['file'],table['fields']) return db table_defs = {'filmes':{'file':'filmes.tsv', 'fields':['id_filme','titulo','tipo','classificacao']}, 'clientes':{'file':'clientes.tsv', 'fields':['id_cliente','nome','morada','c_credito']}, 'alugueres':{'file':'alugueres.tsv', 'fields':['id_aluguer','id_filme','id_cliente', 'data_aluguer','data_entrega']}, }

19

Tabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas Mistas

■ Ler as tabelas para um dicionário de tabelas ("base de dados")• A partir de um dicionário com o esquema das tabelas

def load_db(tables): """Reads all tables into a dictionary Argument is dictionary describing tables""" db = {} for table_name in tables: table = tables[table_name] db[table_name] = load_table(table['file'],table['fields']) return db

In : db = load_db(table_defs) In : db['filmes'] Out: [{'classificacao': 'maiores de 12', 'id_filme': '101', 'tipo': 'Sexto Sentido', 'titulo': 'suspense drama'}, {'classificacao': 'maiores de 6', 'id_filme': '102', 'tipo': 'Regresso ao Futuro', 'titulo': 'comedia aventura'}, ...]

20

Tabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas Mistas

■ Consultas cruzando informação• E.g. Quais os títulos dos filmes alugados e quando foram alugados?

■ Precisamos de cruzar os alugueres com os filmesfilmes: id_filme, tipo, titulo, classificacao

101 Sexto Sentido suspense drama maiores de 12

102 Regresso ao Futuro comedia aventura maiores de 6

...

alugueres:id_aluguer, id_filme, id_cliente, data_aluguer, data_entrega

1001 109 102 05/10/14 05/11/14

1002 106 101 05/12/14 NULL

...

21

Tabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas Mistas

■ Consultas cruzando informação• E.g. Quais os títulos dos filmes alugados e quando foram alugados?

■ Caso geral:• Dadas duas tabelas e um campo em ambas, seleccionar pares que partilham o

mesmo valor nesse campo

• E.g. pares aluguer, filme com o mesmo id_filme

• (todos os pares porque um filme pode ter sido alugado várias vezes)

Filme:

106 Elizabeth drama historico maiores de 12

Aluguer:

1002 106 101 05/12/14 NULL

Junção:

106 Elizabeth drama historico maiores de 12 1002 101 05/12/14 NULL

22

Tabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas Mistas

■ Decompor o problema:• Dado um registo, uma tabela e um campo, emparelhar com todos os registos com

o mesmo valor nesse campo

• Fazer isto para cada registo de uma tabela com todos da outra que tenham omesmo valor no campo

Filme:

106 Elizabeth drama historico maiores de 12

Aluguer:

1002 106 101 05/12/14 NULL

Junção:

106 Elizabeth drama historico maiores de 12 1002 101 05/12/14 NULL

23

Tabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas Mistas

■ Juntar um registo com todos os que partilhem esse campo

def join_rec(rec,table,field): "join record to all in table sharing same value in field" new_table=[] for other_rec in table: if rec[field] == other_rec[field]: new_rec={} for f in rec: new_rec[f] = rec[f] for f in other_rec: new_rec[f] = other_rec[f] new_table.append(new_rec) return new_table

In : filme = db['filmes'][5] In : filme Out: {'classificacao': 'maiores de 12', 'id_filme': '106', 'tipo': 'Elizabeth', 'titulo': 'drama historico'} In : join_rec(filme,db['alugueres'],'id_filme') Out: [{'classificacao': 'maiores de 12', 'data_aluguer': '05/12/14', 'data_entrega': 'NULL', 'id_aluguer': '1002', 'id_cliente': '101', 'id_filme': '106', 'tipo': 'Elizabeth', 'titulo': 'drama historico'}]

24

Tabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas Mistas

■ Alugueres da Joana Fonseca

1001 109 102 05/10/14 05/11/14

1002 106 101 05/12/14 NULL

1003 102 107 05/13/14 NULL

1004 104 102 05/11/14 05/12/14

In : cliente = db['clientes'][1] In : cliente Out: {'c_credito': '123412341234123402', 'id_cliente': '102', 'morada': 'Rua da Guerra, 1234', 'nome': 'Joana Fonseca '} In : join_rec(cliente,db['alugueres'],'id_cliente') Out: [{'c_credito': '123412341234123402', 'data_aluguer': '05/10/14', 'data_entrega': '05/11/14', 'id_aluguer': '1001', 'id_cliente': '102', 'id_filme': '109', 'morada': 'Rua da Guerra, 1234', 'nome': 'Joana Fonseca '}, {'c_credito': '123412341234123402', 'data_aluguer': '05/11/14', 'data_entrega': '05/12/14', 'id_aluguer': '1004', 'id_cliente': '102', 'id_filme': '104', 'morada': 'Rua da Guerra, 1234', 'nome': 'Joana Fonseca '}]

25

Tabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas Mistas

■ Juntar duas tabelas por um campo partilhado

def join(table1, table2, field): "Return all pairs of records with shared field" new_table = [] for rec in table1: new_table.extend(join_rec(rec,table2,field)) return new_table

In : filmes_alug = join(db['filmes'],db['alugueres'],'id_filme') In : filmes_alug [{'classificacao': 'maiores de 6', 'data_aluguer': '05/13/14', 'data_entrega': 'NULL', 'id_aluguer': '1003', 'id_cliente': '107', 'id_filme': '102','tipo': 'comedia aventura','titulo': 'Regresso ao Futuro'}, {'classificacao': 'maiores de 16','data_aluguer': '05/11/14', 'data_entrega': '05/12/14', 'id_aluguer': '1004', 'id_cliente': '102', 'id_filme': '104','tipo': 'ficcao-cientifica terror','titulo': 'Alien'}, {'classificacao': 'maiores de 12', 'data_aluguer': '05/12/14', 'data_entrega': 'NULL', 'id_aluguer': '1002', 'id_cliente': '101', 'id_filme': '106', 'tipo': 'drama historico', 'titulo': 'Elizabeth'}, {'classificacao': 'maiores de 4', 'data_aluguer': '05/10/14', 'data_entrega': '05/11/14','id_aluguer': '1001', 'id_cliente': '102', 'id_filme': '109', 'tipo': 'animacao', 'titulo': 'Idade do Gelo'}]

26

Tabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas Mistas

■ Juntar mais tabelas

In : film_client_alug = join(filmes_alug,db['clientes'],'id_cliente') In : film_client_alug Out[27]: [{'c_credito': '123412341234123407', 'classificacao': 'maiores de 6', 'data_aluguer': '05/13/14', 'data_entrega': 'NULL', 'id_aluguer': '1003', 'id_cliente': '107', 'id_filme': '102', 'morada': 'Boliqueime', 'nome': 'Cavaco Silva', 'tipo': 'comedia aventura', 'titulo': 'Regresso ao Futuro'}, {'c_credito': '123412341234123402', 'classificacao': 'maiores de 16', 'data_aluguer': '05/11/14', 'data_entrega': '05/12/14', 'id_aluguer': '1004', 'id_cliente': '102', 'id_filme': '104', 'morada': 'Rua da Guerra, 1234', 'nome': 'Joana Fonseca ', 'tipo': 'ficcao-cientifica terror', 'titulo': 'Alien'}, {'c_credito': '123412341234123401', 'classificacao': 'maiores de 12', 'data_aluguer': '05/12/14', 'data_entrega': 'NULL', 'id_aluguer': '1002', 'id_cliente': '101', 'id_filme': '106', 'morada': 'Rua da Paz, 20', 'nome': 'Artur Meireles', 'tipo': 'drama historico', 'titulo': 'Elizabeth'}, ...]

27

Tabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas Mistas

■ Confuso, com informação a mais. Vamos seleccionar campos

def select(table, fields): "Return table with selected fields" new_table = [] for rec in table: new_rec = {} for f in fields: new_rec[f] = rec[f] new_table.append(new_rec) return new_table

In : filmes_alug = join(db['filmes'],db['alugueres'],'id_filme') In : film_client_alug = join(filmes_alug,db['clientes'],'id_cliente') In : film_client = select(film_client_alug,['nome','titulo']) In : film_client Out: [{'nome': 'Cavaco Silva', 'titulo': 'Regresso ao Futuro'}, {'nome': 'Joana Fonseca ', 'titulo': 'Alien'}, {'nome': 'Artur Meireles', 'titulo': 'Elizabeth'}, {'nome': 'Joana Fonseca ', 'titulo': 'Idade do Gelo'}]

28

Tabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas Mistas

■ Imprimir mais bonito

def print_table(table, separator = '\t'): "Prints a table using separator" fields = table[0].keys() print(separator.join(fields)) for rec in table: vals = [str(rec[f]) for f in fields] print(separator.join(vals))

In : print_table(film_client) nome titulo Cavaco Silva Regresso ao Futuro Joana Fonseca Alien Artur Meireles Elizabeth Joana Fonseca Idade do Gelo

29

Tabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas Mistas

■ Nota: list comprehension

In : some_list = [] for x in range(10): some_list.append(x) In : some_list Out: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] In : some_list = [x for x in range(10)] In : some_list Out: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

30

Tabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas MistasTabelas Mistas

■ Imprimir mais bonito

def print_table(table, separator = '\t'): "Prints a table using separator" fields = table[0].keys() print(separator.join(fields)) for rec in table: vals = [str(rec[f]) for f in fields] print(separator.join(vals))

In : print_table(film_client,';') nome;titulo Cavaco Silva;Regresso ao Futuro Joana Fonseca ;Alien Artur Meireles;Elizabeth Joana Fonseca ;Idade do Gelo

31

Organizar DadosOrganizar DadosOrganizar DadosOrganizar DadosOrganizar DadosOrganizar DadosOrganizar DadosOrganizar DadosOrganizar Dados

ResumoResumoResumoResumoResumoResumoResumoResumoResumo

32

ResumoResumoResumoResumoResumoResumoResumoResumoResumo

Organizar Dados■ Revisões• Listas e dicionários• Leitura de ficheiros e recursos remotos• Gráficos, matrizes Numpy

■ Ideia de base de dados:• Conjunto de tabelas com registos, relacionando diferentes campos

■ Cruzar informação em tabelas diferentes• (Vamos ver isto melhor na próxima semana)

Leitura adicional:■ Capítulo 15, quando tiver pronto (sem promessas)