Last active
August 28, 2019 13:57
-
-
Save jobdiogenes/ce27eebf85654b6a1bb77e23c747cfe8 to your computer and use it in GitHub Desktop.
data_science_gist_03_pt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"nbformat": 4, | |
"nbformat_minor": 0, | |
"metadata": { | |
"colab": { | |
"name": "data_science_gist_03_pt", | |
"version": "0.3.2", | |
"provenance": [], | |
"collapsed_sections": [], | |
"include_colab_link": true | |
}, | |
"kernelspec": { | |
"name": "python3", | |
"display_name": "Python 3" | |
} | |
}, | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "view-in-github", | |
"colab_type": "text" | |
}, | |
"source": [ | |
"<a href=\"https://colab.research.google.com/gist/jobdiogenes/ce27eebf85654b6a1bb77e23c747cfe8/data_science_gist_03_pt.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "ydD03vekp5db", | |
"colab_type": "text" | |
}, | |
"source": [ | |
"[Índice](https://github.com/jobdiogenes/data-science-recipes/blob/master/gists/index.md)\n", | |
"# Série de Receitas para Ciência de Dados\n", | |
"## Episódio 3 - Repositórios: mergulhando nas rotas de dados de um repositório REST\n", | |
"### Introdução\n", | |
">**Afinal o que são rotas?** bem se você ainda não sabe é porque não foi visitar a documentação do REST API para repositório Fishbase. Se não viu ainda, tudo bem, mas agora você deve ir lá (https://fishbaseapi.readme.io/docs) dar uma olhada e ver as diversas rotas (_route_) para trazer dados. \n", | |
"\n", | |
">**Orientações** daqui pra frente os exemplos e os exercícios terão códigos mais extensos. Por isso preste muita atenção a identação. (dois espaços) para cada nível, que é a forma que o python usa pra definir a abrangência de um código de nível (if, while, for, etc). No terminal, usar o ipython3 é melhor que o python3, pois ele colore o código de acordo com o significado e também possui documentação e autocompleta comandos. \n", | |
"\n", | |
"Por exemplo, no último exemplo do episódio 2, a variável **r** se referia ao resultado da busca _get_ ao repositório e a variável **especies** recebe o contaúdo de **r[''data']**, como informado no 1º episódio, tudo em python é um objeto. E no caso do ipyhon e também de editoes de código como Aton, ou VsCode, que possuem suporte pra python, eles oferecem a opção de informar quais métodos estão disponíveis para tal objeto. No caso do ipython3 por exemplo, ao digitar **r.** e pressionar a tecla tab, ele mostrará os métodos disponíveis para o tipo dicionário ex: keys(),items(),values(), e da mesma forma os correspondentes para a variável especie e para função _get_. No Atom e no VsCode, logo ao digitar o **.** (ponto) já é exibido as opções. Esses editores, são muito usados por quem escreve código em diversas linguagens, como **Python**, **R**, **Julia**, **Javascript**, etc, pois além de autocompletar fazem análise do código identificando possíveis erros. :). Por agora, usar no colab, ou por algum dos terminais (no seu computador) or na nuvem, já atende ao propósito de aprendener. Você é livre pra experimentar todas essas opções, python, ipython, Jupyter, Atom, VcCode ou Colab. Qualquer dessas opções você poderá executar o python3 e obter os resultados. \n", | |
"\n", | |
"##Meta\n", | |
"\n", | |
"A meta deste episódio é entender e praticar como obter dados de diferentes rotas disponíveis pelo Fishbase API, interligando dados de uma rota com uma ou mais rotas. Com isso você vai entender como é possível, unir dados de diferentes contextos para atender as nossas necessidades. \n", | |
"\n", | |
"## O que iremos ver?\n", | |
"Bem, como se pode entender pelo próprio nome Ciência de Dados se trata de lidar com dados. É fundamental quando se trata de obter dados de repositórios, conhecer a estrutura organizacional (taxonomia) rotas que os dados estão dispostos, o que cada rota oferece de conteúdo e os recurso da API. **Importante** cada respositório possui uma API com recursos e parâmetros diferentes, por isso sempre que for olhar outra base, deve-se pesquisar nele ler a documentação da API. **Spoiler** no próximo episódio terá consultas unindo bases diferentes. \n", | |
"\n", | |
"E neste episódio teremos os seguintes itens:\n", | |
"1. [x] Como estudar as rotas e os dados para realizar nossas pesquisas\n", | |
"1. [x] Interligando rotas e extraindo somente os dados que queremos.\n", | |
"\n", | |
"### Item 1 - Estudando as rotas e os dados\n", | |
"A página de [documentação do Fishase API](https://fishbaseapi.readme.io/docs) traz a lista de todas as rotas e informações básica sobre os parâmetros que podem ser usados. E ao você olhar pela primeira vez, pode achar estranho não haver descrição do que é cada rota. Sim, a maioria tem nomes que iremos entender facilmente, como _taxa_, _species_, _diet_, etc, tem ainda a opção de realizar uma pesquisa ali mesmo e ver o conteúdo que retorna. Isso é muito bom, e nem todos repositórios tem isso. \n", | |
"\n", | |
"E agora, você ira pensar, vou ter de advinhar o que significa? . No caso do Fishbase não!, apesar de não aparecer na descrição quando você clica sobre alguma rota. O fishbase oferece a descrição do conteúdo na rota /docs. Parece estranho isso, afinal você esta ali e gostaria de saber do que se trata. Mas, entenda, APIs são feitas pra usar via consulta por programação e não pelo site, apesar de ser bacana poder testar ali. É um teste limitado, mas já ajuda ver o que retorna de conteúdo. \n", | |
">**Como descobrir?** pois é, ler a documentação organizada é a primeira parte, mas pode ser insuficiente. Por isso, em todo tipo de API, a principal atividade inicial é chamar várias rotas pra ver do que realmente se trata. Ai você vê que existe uma rota **/docs**, que remete a documentação, vê outra com o nome **/heartbeat** e se pergunta, \"que raio é isso?\". Fácil, chame a rota e vê o que retorna. Ou seja, é ao mesmo tempo um processo empírico e metódico, que envolve ler e experimentar.\n", | |
">** __APIs não são só pra buscar dados__, elas servem também pra enviar e atualizar dados por colaboradores da base que possuem registro e acesso a atualização. \n", | |
" \n", | |
" Vamos aos experimentos:\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "bmckuIaAEqrv", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"source": [ | |
"# essas definições se repetem a cada bloco de código porque eles podem ser \n", | |
"# executados individualmente, mas se esta executando no terminal, só é \n", | |
"# preciso quando abre o ipython3 ou o python3\n", | |
"\n", | |
"# iniciando\n", | |
"from requests import get\n", | |
"h = \"https://fishbase.ropensci.org/\"\n", | |
"\n", | |
"# chamando a primeira rota\n", | |
"r = get(h+'/heartbeat').json()\n", | |
"print(r,'\\n')\n", | |
"\n", | |
"# > o que você encontra é uma lista de todas rotas e parâmetros \n", | |
"\n", | |
"# lembram dos parâmetros 'limit' e 'offset' vamos definir para exibir 1 só\n", | |
"# exibir o docs\n", | |
"r = get(h+'/docs',params={'limit':1}).json()\n", | |
"print(r,'\\n')\n", | |
"\n", | |
"# você observa que não limitou. motivo? tá lá na documentação,\n", | |
"# a rota /docs não recebe esse parâmetro\n", | |
"\n", | |
"# você observa também que os dados assim como no taxa estão no array 'data'\n", | |
"# que contém um dicionário\n", | |
"\n", | |
"# vamos exibir as chaves para saber os campos 'fields' disponíveis do /doc.\n", | |
"# sim, você pode simplesmente ler um registro todo, mas o conteúdo pode ser \n", | |
"# extenso e dificultar. \n", | |
"\n", | |
"# exibindo apenas o registro inicial \n", | |
"print(r['data'][0].keys())\n", | |
"\n", | |
"# vamos exibir esse conteúdo de forma mais amigável numa única linha de comando\n", | |
"for doc in get(h+'/docs').json()['data']: print(doc['table'],':',doc['description'],'\\n') \n", | |
"\n", | |
"# ficou bem mais fácil de ler não é?\n", | |
"\n", | |
"# lendo a doc descobrimos que a rota /country contêm a lista de espécies \n", | |
"# que ocorrem num país e a rota /countref tem a descrição dos países.\n", | |
"\n", | |
"# documentação online também informa que a countref alem dos parâmetros 'limit'\n", | |
"# 'offset' e 'fields' permite usar como filtro todos os campos exibidos.\n", | |
"\n", | |
"# vamos ver então quais são para a rota /countref\n", | |
"print('Campos para /countref', '\\n', get(h+'/countref',params={'limit':1}).json()['data'][0].keys(),'\\n')\n", | |
"\n", | |
"# e agora para a /country\n", | |
"print('Campos para /country', '\\n', get(h+'/country',params={'limit':1}).json()['data'][0].keys(),'\\n')\n", | |
"\n", | |
"# se o nome dos campos não é suficiente informativo exibimos então um registro\n", | |
"print('Conteúdo para /countref', '\\n', get(h+'/countref',params={'limit':1}).json()['data'][0],'\\n')\n", | |
"\n", | |
"# agora sabemos que o campo C_Code deve ser o que une country e countref\n", | |
"# e que o nome do país esta em vários campos em vários idiomas\n", | |
"\n", | |
"# vamos exibir sobre o Brasil\n", | |
"brasil = get(h+'/countref',params={'PORTUGUESE': 'Brasil'}).json()['data'][0]\n", | |
"print('Conteúdo para Brasil', '\\n', brasil,'\\n')\n", | |
"\n", | |
"# bem agora vamos obter e exibir apenas o nome e o código de todos países do \n", | |
"# mesmo continente. temos 3 opções. iremos de 'Continent' e com limite 99\n", | |
"# grande para retornar todos países\n", | |
"continente = brasil['Continent']\n", | |
"print(continente,'\\n')\n", | |
"\n", | |
"print('Países do continente',continente)\n", | |
"print('C_Code,GSI_Name,PORTUGUESE')\n", | |
"for pais in get(h+'/countref',params={'limit':99,'Continent': continente, 'fields' : 'C_Code,GSI_Name,PORTUGUESE'}).json()['data']:\n", | |
" print(pais['C_Code'],',',pais['GSI_Name'],',',pais['PORTUGUESE'])\n", | |
"print('---------------------------------\\n')\n", | |
"\n", | |
"# você observou que nem todos GSI_Name e PORTUGUESE contem dados. \n", | |
"# então devemos ver qual é o campo que sempre tem dados. \n", | |
"americadosul = get(h+'/countref',params={'limit':99,'Continent': continente, 'fields' : 'C_Code,PAESE,Note,GSI_Name,PORTUGUESE'}).json()['data']\n", | |
"for pais in americadosul: \n", | |
" for chave,valor in pais.items():\n", | |
" print(chave,':',valor,',',end='')\n", | |
" print()\n", | |
"# observou o end='', o motivo disso é que por padrão o print poe '\\n' nova linha\n", | |
"# dessa forma exibe todos os campos numa mesma linha e depois coloca nova linha\n", | |
"# Pelo resultado visual o nome do pais esta garantido no campo 'PAESE'\n", | |
"\n", | |
"# e se fosse muitos países como fazer com mais precisão?\n", | |
"# R: contamos usando dicionario\n", | |
"contadores = {'total' : 0}\n", | |
"for pais in americadosul: \n", | |
" for chave,valor in pais.items():\n", | |
" if chave not in contadores.keys():\n", | |
" contadores[chave] = 0\n", | |
" if valor is not None:\n", | |
" contadores[chave] += 1\n", | |
" contadores['total'] += 1 \n", | |
"print(contadores)" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "IT1DN6ONBgqY", | |
"colab_type": "text" | |
}, | |
"source": [ | |
"### Item 2 - Interligando os dados e extraindo\n", | |
"Até agora já aprendemos a explorar o conteúdo de uma rota por vez, saber quais são seus campos e saber se estão preencidos. Como podemos observar, as rotas oferecem conteúdos diferentes, mas possuem campos de conexão. No caso de países é o C_Code, no caso de Espécies é o SpecCode\n", | |
"\n", | |
"Usando essas informações vamos extrair dados unindo rotas.\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "329Fl1RuD8ej", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"source": [ | |
"# inicio\n", | |
"from requests import get\n", | |
"h = \"https://fishbase.ropensci.org\"\n", | |
"\n", | |
"# 1) Como obter todas as fotos das espécies disponíveis do gênero serrasalmus.\n", | |
"#\n", | |
"# - se você ainda não viu quais os campos de cada rota veja agora das\n", | |
"# rotas /taxa e /species. olhe acima e repita mudando as rotas\n", | |
"#\n", | |
"# - você verá que a rota /taxa contem a lista de especies \n", | |
"# e a rota /species contem o link para imagem.\n", | |
"\n", | |
"# pegar de/taxa lista de especies de serrasalmus\n", | |
"lista = get(h+'/taxa',params={'Genus': 'serrasalmus','limit':99}).json()['data']\n", | |
"serrasalmus = []\n", | |
"for peixe in lista:\n", | |
" especie_codigo = peixe['SpecCode']\n", | |
" dados = get(h+'/species', params={'SpecCode' : especie_codigo}).json()['data'][0]\n", | |
" serrasalmus.append({'Código' : dados['SpecCode'],'Espécie' : dados['Species'], 'FotoURL' : dados['image']})\n", | |
"\n", | |
"for peixe in serrasalmus: print(peixe)\n", | |
" \n", | |
"# aqui vocẽ viu que nem todas as espécie possuem foto.\n", | |
"# é uma oportunidade de vocẽ publicar uma e enviar para enviar\n", | |
"\n", | |
"# se estiver usando o colab ou jupyter\n", | |
"# o código a seguir irá exibir as fotos\n", | |
"\n", | |
"# se NÂO estiver no Colab ou Jupyter \n", | |
"# comente a linha: display(Image ...\n", | |
"from IPython.display import Image, display\n", | |
"\n", | |
"for peixe in serrasalmus: \n", | |
" if peixe['FotoURL'] is not None:\n", | |
" display(Image(url=peixe['FotoURL']))\n", | |
" print(peixe['FotoURL'])" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "y2pBANvvxU6R", | |
"colab_type": "text" | |
}, | |
"source": [ | |
"### Tarefa\n", | |
"\n", | |
"Usando os conhecimentos vistos acima liste todas as espécies de Serrasalmus existentes em cada país da america do sul e se é nativa. Dica: a relação pais x espécie esta na rota /country. A resposta você pode ver [aqui](https://github.com/jobdiogenes/data-science-recipes/blob/master/gists/code/answer-e03t01.py). Não veja isso agora. Faça esta tarefa. \n", | |
"\n", | |
"> ***Fique atento grandes novidades para o próximo episódio***" | |
] | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment