Skip to content

Instantly share code, notes, and snippets.

@jobdiogenes
Last active August 28, 2019 13:57
Show Gist options
  • Save jobdiogenes/ce27eebf85654b6a1bb77e23c747cfe8 to your computer and use it in GitHub Desktop.
Save jobdiogenes/ce27eebf85654b6a1bb77e23c747cfe8 to your computer and use it in GitHub Desktop.
data_science_gist_03_pt
Display the source blob
Display the rendered blob
Raw
{
"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