Guia Completo: 10 Comandos em Python Essenciais para Análise de Dados

Os principais comandos para iniciar a análise exploratória de dados

Wilmara Alves
comunidadeds
18 min readDec 8, 2023

--

Fonte: <a href=”https://br.freepik.com/vetores-gratis/ilustracao-de-api-de-design-plano-desenhado-a-mao_25860683.htm#page=2&query=python&position=14&from_view=search&track=sph&uuid=585861b3-a0fd-4f82-a3e7-7b7367a60df3">Imagem de pikisuperstar</a> no Freepik

Python é uma linguagem vital para cientistas de dados por sua simplicidade, flexibilidade e poder analítico. Sua vasta gama de bibliotecas especializadas, como Pandas, NumPy e Matplotlib, oferece ferramentas robustas para manipulação, análise e visualização de dados. A facilidade de leitura e escrita do código em Python permite aos cientistas de dados concentrarem-se na lógica e nos algoritmos, agilizando o desenvolvimento e a implementação de soluções. Isso explica também o motivo de ser uma das linguagens mais solicitadas por recrutadores e nos motiva a dominá-la antes das demais.

Na análise exploratória de dados, os principais comandos em Python são empregados para entender a estrutura dos conjuntos de dados. O Pandas, por exemplo, oferece funcionalidades como leitura de dados de diferentes fontes, manipulação de tabelas (DataFrames) e estatísticas descritivas. Com comandos simples como head(), describe(), info(), os cientistas de dados podem examinar rapidamente os dados, identificar valores ausentes, estatísticas básicas e ter uma visão geral dos tipos de dados presentes no conjunto.

Além disso, a visualização de dados é crucial na exploração inicial. Bibliotecas como Matplotlib e Seaborn permitem criar gráficos e visualizações informativas para entender a distribuição, correlação e padrões nos dados. Comandos para plotagem de gráficos como plot(), hist(), scatter(), entre outros, capacitam os cientistas de dados a comunicar insights de forma clara e eficaz durante a análise exploratória.

Python se tornou o coração das atividades de análise de dados devido à sua simplicidade, vasta comunidade de apoio e às ferramentas poderosas que oferece. Através de bibliotecas especializadas e comandos intuitivos, os cientistas de dados podem realizar uma análise exploratória completa, compreendendo a estrutura, identificando padrões e preparando os dados para análises mais avançadas. Assim, te apresentarei comandos básicos que poderão guiar os estudos de cientistas de dados iniciantes e despertar em você a vontade de praticar e fixar estes conhecimentos iniciais.

Aproveite para assistir este vídeo sobre o primeiro dia utilizando Python.

Escolhendo a IDE

Antes de iniciar os estudos é necessário escolher uma IDE ( Integrated development environment ), ou seja, um ambiente de desenvolvimento integrado que nada mais é do que um programa de computador que permita o desenvolvimento de softwares. Enquanto cientistas de dados, utilizar IDEs nos permite usufruir do mesmo espaço de desenvolvimento dos programadores, possibilitando trabalhar com linguagens de programação capazes de, através de linhas de códigos, realizar análises automatizadas.

Existem hoje vários IDEs disponíveis para utilização, como por exemplo o VScode, Jupyter, PyCharm, etc. Com o tempo de prática você poderá escolher aquela que melhor atende às suas necessidades, mas por hora sugiro a utilização de um simulador de IDE em nuvem muito conhecido, o Google Collaboratory, ou Google Colab, serviço hospedado do Jupyter Notebook.

Google Colaboratory SVG (vector) Logo, Disponível em https://commons.wikimedia.org/wiki/File:Google_Colaboratory_SVG_Logo.svg

Há algumas vantagens em iniciar com o Google Colab. Primeiramente, é uma plataforma em nuvem por meio do Google Drive pronta para programação. O acesso se dá justamente a partir do login com uma conta gmail, portanto acessível e gratuito. O fato da nuvem ser o Google Drive possibilita o compartilhamento de notebooks e colaboração em tempo real, um grande facilitador para realização de trabalhos em equipe. Em segundo lugar, temos a vantagem de vir com alguns pacotes pré instalados, como Pandas, NumPy e Matplotlib.

O Colab poderá fornecer inclusive recursos de processamento, outra grande vantagem. Na minha experiência, já fiz uso de uma máquina com memória RAM de 12 GB, enquanto meu notebook pessoal só tinha 4GB. O fornecimento de Unidades de Processamento Central (CPU) e gráficas (GPU) são de grande valia quando estamos diante de análises de grandes conjuntos de dados e agiliza o processamento de algoritmos de machine learning que podem consumir mais memória de processamento. Vamos combinar que é uma evolução e tanto.

Apresentadas as vantagens do Colab. Todos os principais comandos em python que utilizarei para te nortear a realizar análises básicas iniciais, foram realizados nele. Por isso te convido a iniciarmos esta jornada de comandos básicos do python no colab.

Principais comandos em Python

Para iniciarmos os estudos é preciso definirmos o local onde iremos pesquisar sobre os comandos. Portanto, irei definir como fonte a própria documentação do da biblioteca python. Sempre que estou estudando sempre pesquiso nas documentações oficiais primeiramente e quando não entendo, ou mesmo para aprofundar o conhecimento, sigo por outras fontes como youtube, fóruns e Comunidade DS (discussões no discord, colegas, monitores, professores, etc)

1.1 Preparando o colab

Inicialmente iremos acessar o colab através do site https://colab.google/ , conforme a interface abaixo.

Ao clicar em ‘New Notebook’, você abrirá um novo notebook conforme imagem a seguir. A partir daí você já pode escrever suas primeiras linhas de código. Observe que há, no canto superior esquerdo, o nome do seu arquivo acrescido do .ipynb. Minha sugestão é que renomeie com o nome do seu projeto. Caso já esteja logado na conta google, automaticamente seu notebook estará salvo no seu drive.

Arquivo renomeado, irei realizar o upload de um dataset para seguirmos para os principais comandos. O Upload é realizado acessando a pasta de arquivos do google colab, no lado esquerdo, como mostra a figura 1. Na Figura 2, ao clicar no ícone do papel com seta para cima, iremos finalmente realizar o upload de um arquivo csv, de sua escolha. Um arquivo csv nada mais é do que um arquivo de texto que separa valores por vírgulas. É neste formato de arquivo que se encontram a maioria das bases de dados.

Figura 1
Figura 2

Obs.: A escolha do dataset(Arquivo de dados que irá utilizar) fica a seu critério. Uma sugestão é utilizar dados do kaggle ou Portal Brasileiro de Dados Abertos.

1.2 Read

No momento que escrevo este artigo a biblioteca Pandas encontra-se na versão 2.1.3. Para acessar basta acessar o link https://pandas.pydata.org/docs/.

Agora sim, vamos ao primeiro comando, o responsável por realizar a leitura do arquivo que o cientista ou analista de dados quer avaliar. Este comando funciona a partir do acionamento da biblioteca em questão, no caso, pandas a partir do comando da própria biblioteca, o read_csv(). Ou seja, é como se eu determinasse ‘pandas: leia o arquivo csv’.

Então, vamos executar o comando. Para isso devemos importar a biblioteca pandas, pois apesar de estar previamente instalada no colab, sempre que usarmos uma biblioteca temos que importar ela no notebook.

É visível que algumas palavras ficam com cores diferentes, no caso as palavras ‘import’ e ‘as’ são palavras reservadas, ou seja, elas desempenham alguma função específica no python. Perceba que o com o import pandas as pd, eu importo a biblioteca com a palavra ‘import’ e a apelido de pd com a palavra reservada ‘as’.

Lendo o arquivo com o read_csv():

Conforme mostrado na figura acima, temos que ‘pd’ irá acionar a biblioteca pandas e realizará a leitura do arquivo csv a partir do read_csv(). Dentro do parêntese é indicado o caminho do arquivo. Por fim guardei a leitura do arquivo dentro da variável df. A nomenclatura da variável que irá guardar a informação pode ser qualquer uma, desde que não seja uma palavra reservada. Aqui escolhi df por ser uma abreviação de DataFrame e assim entendo que é o DataFrame inicial.

Existe ainda uma forma de automação de leitura do arquivo sempre que retomar o trabalho no dataset quando utilizar o google colab. Isso te permite evitar realizar o upload do arquivo sempre que entrar no notebook. Segue o macete.

A leitura do arquivo automatizada ficaria do seguinte modo:

Ressalto que esta automação implicará no acesso do google colab ao seu drive e por isso é solicitada uma autorização sua para que o google colab acesse seu drive.

1.3 Head

O .head() é um dos comandos mais utilizados pelo cientista de dados, pois ele permite visualizar o que seria um cabeçário, ou seja, a parte inicial do seu DataFrame. Assim, temos uma rápida compreensão dos nossos dados, pois conseguimos verificar todas as colunas e as primeiras linhas, por padrão as cinco primeiras, do início do DataFrame. Esta apresentação permite identificar o que é representado por cada coluna e deste modo começamos a nossa análise exploratória dos dados.

Esse comando é crucial para uma visão geral rápida, ajudando a identificar potenciais problemas nos dados, como valores ausentes, inconsistências ou formatos inesperados. Além disso, oferece um ponto de partida para entender a distribuição dos dados em cada coluna e para decidir quais operações ou limpezas podem ser necessárias antes de avançar com análises mais detalhadas. Veja abaixo.

Observe a saída:

Caso queira verificar mais linhas, além das 5 primeiras é só inserir a quantidade dentro do parêntese.

O dataset acima possui 24 colunas e por isso a saída acaba escondendo algumas das colunas. Com outro comando associado ao head, estou falando do transposto, representado pelo ‘.T’, podemos mudar a apresentação trazendo as cinco primeiras linhas para colunas e as colunas para as linhas. Com isso conseguimos visualizar todas as colunas.

Saída do df.head com T (Transposto)

1.4 Shape

O comando df.shape em Pandas é fundamental para entender a estrutura do conjunto de dados, fornecendo informações precisas sobre sua dimensionalidade. Ao utilizá-lo, você obtém uma linha com dois valores: o número de linhas e o número de colunas do DataFrame. Essa informação é crucial no início de qualquer análise, pois oferece uma visão imediata da quantidade de dados que você está lidando e da sua organização tabular. Compreender o tamanho do DataFrame não apenas ajuda a ter uma noção da escala dos dados, mas também é útil para pré-alocar recursos computacionais ou preparar visualizações, permitindo uma análise mais eficiente e direcionada.

Além disso, o df.shape é valioso para verificar a integridade dos dados após operações de manipulação ou limpeza. Ao realizar transformações nos dados ou fusão de conjuntos, é essencial confirmar se o número de linhas e colunas do DataFrame resultante corresponde às expectativas. Qualquer discrepância no tamanho pode indicar problemas na manipulação dos dados, como fusões incorretas ou operações que afetaram inadvertidamente a estrutura do DataFrame, destacando a importância desse comando para garantir a qualidade e a consistência dos dados durante todo o processo analítico.

Segue aplicação:

O dataset que estou utilizando possui 103.904 mil linhas e 24 colunas.

1.5 Info

O comando df.info() em Pandas é um recurso crucial durante a análise de dados, fornecendo um resumo conciso, porém informativo, sobre a estrutura do DataFrame. Ao utilizá-lo, você obtém informações essenciais, como o nome das colunas, o número total de entradas não nulas em cada coluna e o tipo de dados presente em cada uma delas. Isso é fundamental para entender a integridade dos dados, identificar rapidamente possíveis problemas, como valores ausentes ou tipos de dados incompatíveis, e determinar as etapas necessárias para limpeza ou preparação dos dados antes de análises mais avançadas.

Utilizando o df.info():

Vamos analisar cada seção:

  • <class ‘pandas.core.frame.DataFrame’>: Indica que o objeto é uma instância da classe DataFrame da biblioteca Pandas, mostrando o tipo de dados.
  • RangeIndex: 103904 entries, 0 to 103903: Indica que o DataFrame possui um índice que vai de 0 a 103903, com um total de 103904 entradas.
  • Data columns (total 24 columns): Informa que o DataFrame possui 24 colunas no total.
  • Linhas de Informação de Colunas: Cada linha abaixo do cabeçalho das colunas fornece informações detalhadas sobre cada coluna no DataFrame, incluindo o nome da coluna, o número de valores não nulos (Non-Null Count) e o tipo de dados (Dtype). Isso é útil para entender a estrutura dos dados, como a presença de valores ausentes, os tipos de dados em cada coluna (int64, float64 ou object) e a distribuição geral dos dados.
  • memory usage: 19.0+ MB: Mostra a quantidade aproximada de memória utilizada pelo DataFrame, importante para avaliar o impacto do conjunto de dados na memória do sistema.

Em síntese, o df.info() permite otimizar o uso de recursos computacionais, especialmente ao lidar com grandes conjuntos de dados. Ao ter uma visão clara da quantidade de memória utilizada por cada coluna e dos tipos de dados presentes, os cientistas de dados podem tomar decisões informadas sobre como reduzir o uso de memória, convertendo tipos de dados para formatos mais eficientes, o que é crucial para garantir o desempenho e a eficiência das operações realizadas nos dados, especialmente em ambientes computacionais limitados.

1.6 Isnull

O comando df.isnull().sum() é essencial para identificar rapidamente a quantidade de valores nulos em cada coluna do DataFrame. Ao utilizá-lo, você obtém um resumo claro e direto do número de valores ausentes em cada coluna. Identificar valores nulos é fundamental, pois eles podem influenciar negativamente análises estatísticas, modelagem de dados e visualizações, além de serem potenciais indicadores de problemas na coleta ou no processamento dos dados.

Além disso, o df.isnull().sum() permite tomar decisões informadas sobre como lidar com valores ausentes durante o processo de limpeza e preparação dos dados. Dependendo do contexto e do volume de valores nulos em uma determinada coluna, é possível optar por estratégias como remoção das linhas afetadas, preenchimento dos valores ausentes com médias ou valores específicos, ou até mesmo aplicação de métodos mais complexos para imputação de dados faltantes. Essa análise inicial é crucial para garantir a qualidade dos dados e a precisão das análises subsequentes.

Aplicando o isnull:

Conforme saída apresentada foi identificado um total de 310 números ausentes na coluna Delivery delay in minutes. Esta coluna indica o atraso de entregas em minutos. Um dos motivos para não haver dados inseridos nestas 310 linhas é que nestas entregas não houve atrasos. Outro explicação seria erro na coleta do dado. Sabendo disso, o cientista de dados vai definir como ajustar estes valores. Se deixa como está e entende que estes foram os casos de entrega em tempo hábil, ou se irá excluir estas linhas, ou ainda se vai mudar para a média ou valores específicos.

1.7 Mean

O comando mean() é uma ferramenta essencial na análise de dados, permitindo calcular a média aritmética dos valores em um conjunto de dados. Ao aplicar mean() a uma série ou coluna específica de um DataFrame no Pandas, obtemos o valor médio dos dados numéricos nessa coluna. Essa medida é fundamental para compreender a tendência central dos dados, proporcionando um ponto de referência para entender o comportamento médio da variável em questão. Isso é particularmente útil ao lidar com variáveis contínuas, como idade, renda ou tempo, fornecendo uma visão geral do valor médio e ajudando a identificar discrepâncias ou desvios significativos.

Além disso, o mean() é crucial para análises estatísticas mais avançadas, pois serve como base para avaliar a distribuição dos dados e para comparar diferentes conjuntos de dados. Comparar a média entre diferentes grupos ou períodos de tempo pode revelar tendências ou diferenças significativas nos dados, auxiliando na identificação de padrões e na formulação de hipóteses para investigações mais detalhadas. Essa medida descritiva é valiosa no contexto de estatísticas descritivas e análises exploratórias, fornecendo um indicador inicial sobre a natureza central dos dados e facilitando a compreensão de suas características.

Aplicando o mean no dataframe ele irá calcular a média de todas as variáveis quantitativas, conforme exemplo abaixo.

Nesta saída de médias podemos observar que várias colunas estão com médias em torno de 3. Estas colunas no dataset em uso se referem às características das lojas como limpeza, higiene do banheiro, apresentação dos produtos na loja, dentre outras. Portanto, isto implica que no geral as lojas apresentam um serviço mediano.

1.8 Describe

O comando describe() desempenha também um papel crucial na análise primária de um conjunto de dados, fornecendo estatísticas descritivas das colunas numéricas. Essas estatísticas incluem a contagem de valores não nulos, a média, o desvio padrão, os valores mínimo e máximo, além dos quartis, oferecendo uma visão abrangente da distribuição e da centralidade dos dados. Isso permite aos cientistas de dados compreenderem rapidamente a natureza dos dados, identificarem outliers, entenderem a dispersão e até mesmo destacarem possíveis problemas, como valores extremos que podem afetar análises posteriores.

Observe a aplicação do describe:

Analisando esta tabela consigo extrair alguns pontos. Por exemplo, no geral a média de idade, representada na coluna ‘Age’ é de 39 anos, o primeiro quartil, representado pelos 25% dos dados apresenta idade média de 27 anos, no segundo quartil a idade média é de 40 e o terceiro quartil, a idade está em 51 anos na média. A diferença entre a mediana (40 anos) e a média (39 anos) sugere que a distribuição das idades pode estar um pouco enviesada para a direita, ou seja, pode haver alguns valores mais altos (outliers) puxando a média para cima em relação à mediana. Essas estatísticas indicam que a maioria das idades está concentrada entre 27 e 51 anos, com a mediana próxima ao meio desse intervalo.

Como vimos, além de oferecer insights sobre a distribuição dos dados, o df.describe() é valioso para comparar diferentes variáveis dentro do conjunto de dados. Ao examinar as estatísticas descritivas de várias colunas, os analistas podem identificar padrões, relações e discrepâncias entre as variáveis numéricas, permitindo um entendimento mais profundo do comportamento dos dados e orientando a seleção de métodos de análise estatística ou modelagem mais apropriados para explorar os dados de maneira mais eficaz.

1.9 Unique

O comando df.unique() é fundamental para entendermos a variedade e a distribuição dos valores únicos em uma coluna específica de um DataFrame. Ao aplicar esse comando, obtém-se uma lista dos valores únicos presentes na coluna selecionada, permitindo uma rápida e clara compreensão das diferentes categorias ou tipos de dados presentes. Essa função é particularmente útil para colunas categóricas ou de classificação, como gênero, tipo de cliente ou categoria de produto, fornecendo insights sobre a diversidade e a frequência de cada categoria.

É importante lembrar que para aplicar o comando, precisamos selecionar a coluna desejada através da identificação desta entre aspas e dentro de colchetes. Veja abaixo.

A saída é representada por uma lista contendo todas as idades presentes no dataset. Isso pode nos levar a fazer análises que envolvam a idade, mas após agrupá-las em faixas etárias, por exemplo. Isto permite melhor visualização e até entendimento dos dados.

Ao selecionar outra coluna percebemos que os dados possuem dois grupos de tipo de compra.

Saída:

A importância do df.unique() reside na capacidade de identificar e compreender a amplitude de dados distintos, possibilitando a tomada de decisões informadas durante a análise exploratória. Ao visualizar os valores únicos, os cientistas de dados podem identificar padrões, verificar a consistência dos dados e até mesmo detectar possíveis erros ou valores discrepantes. Essa compreensão inicial é crucial para a preparação dos dados, ajudando na formulação de estratégias adequadas de limpeza, transformação ou categorização dos dados, garantindo uma base sólida para análises mais avançadas.

1.10 Corr

O comando df.corr() nos possibilita compreender as relações lineares entre diferentes variáveis numéricas em um DataFrame. Ao aplicar esse comando, é gerada uma matriz de correlação, fornecendo coeficientes que indicam a força e a direção das relações entre pares de variáveis. Esse recurso é fundamental para identificar padrões, associações e dependências entre os dados, auxiliando na compreensão de quais variáveis têm maior influência umas sobre as outras e como elas podem estar relacionadas.

A importância do df.corr() está sintetizada na capacidade de identificar correlações significativas entre variáveis, o que é crucial para direcionar análises mais aprofundadas. Uma correlação forte ou inversa entre variáveis pode indicar possíveis insights ou relações de causa e efeito, fornecendo uma base para investigações mais detalhadas ou modelagem preditiva. Essa análise de correlação é essencial para os cientistas de dados priorizarem variáveis-chave, descartarem multicolinearidade (correlações altas entre variáveis independentes) em modelos preditivos e direcionarem estratégias de feature engineering para melhorar a performance dos modelos de machine learning. Visualize a aplicação a seguir.

A saída é um tabelão com as correlações entre as colunas. Quanto mais próximos de 1, a uma indicação de correção forte entre as variáveis, explicando que quando uma se eleva há uma tendência de elevação na outra. Por outro lado, quanto mais próximos de -1, uma forte correlação negativa está acontecendo, pois quando uma variável aumenta a outra tende a diminuir.

Uma opção ideal de visualizar o corr é por meio de um gráfico, pois facilita o entendimento. Para isso será necessário importar duas bibliotecas de visualização, a matplotlib e seaborn.

Com a visualização gráfica podemos observar melhor as correlações e extrair insights importantes. Para além dos insights, descartar variáveis com influência menor ou mesmo irrelevantes na futura utilização de modelos de machine learning.

1.11Hist

Por fim, o comando df.hist() é uma ferramenta valiosa para os cientistas de dados explorarem a distribuição dos dados de um DataFrame por meio da criação de histogramas para cada coluna numérica. Esse método simplifica a visualização das frequências dos valores em diferentes intervalos ou bins, permitindo identificar padrões, assimetrias, picos e tendências nos dados. Essa representação gráfica é essencial para compreender a forma e a dispersão dos dados, possibilitando observar se eles se aproximam de distribuições conhecidas, como a normal, uniforme ou assimétrica, o que pode orientar escolhas de técnicas estatísticas ou de modelagem mais apropriadas para análises subsequentes.

A importância do df.hist() reside na capacidade de oferecer uma visão rápida e visual da distribuição dos dados, sendo um ponto de partida essencial na análise exploratória. Ao examinar os histogramas de diferentes variáveis, os cientistas de dados podem identificar possíveis outliers, entender a concentração dos valores em determinados intervalos e visualizar a dispersão dos dados, contribuindo para decisões sobre estratégias de pré-processamento, detecção de anomalias e seleção de features para modelos preditivos. Essa ferramenta permite uma compreensão inicial e visualmente intuitiva das características essenciais dos dados, facilitando a identificação de insights e direcionando investigações mais detalhadas. Veja o exemplo prático abaixo.

Diante deste histograma, podemos verificar que as avaliações dos serviços recebem notas de 0 a 5, ou seja quanto mais próximo de 5, temos um excelente serviço e quanto mais próximo de 0, péssima qualidade de serviço. Nos Instore-Wifi e no easy online shopping, podemos observar quase o mesmo gráfico, ambos demonstrando quase metade dos dados com notas de 0 a 2 e a outra metade de 3 a 5. Isso nos permite avaliar que na média, metade das pessoas estão satisfeitas e a outra metade não. Estas avaliações iniciais podem gerar várias hipóteses para validação.

Ainda pensando em te auxiliar a absorver os comandos básicos de Python mais utilizados na análise de dados, te apresento este vídeo que traz outros comandos também importantes, a fim de te acrescentar mais fontes de conhecimento. Python — Top 10 Funções para análise de dados

Conclusão

Esses 10 comandos básicos em Python para análise de dados fornecem uma base sólida para explorar e compreender conjuntos de dados. Desde a leitura inicial com pd.read_csv() até a criação de visualizações com df.hist(), cada comando desempenha um papel fundamental na compreensão dos dados. Através do uso desses comandos, é possível entender a estrutura do conjunto de dados, identificar valores ausentes, calcular estatísticas descritivas, explorar correlações e visualizar distribuições. No entanto, para ir além e aplicar esses comandos na prática, é crucial encontrar um conjunto de dados interessante e desafiador para análise.

A ação de encontrar um conjunto de dados relevante e aplicar esses comandos é essencial para aprimorar as habilidades de análise de dados. Ao escolher um conjunto de dados de interesse, seja sobre economia, saúde, educação ou qualquer outro tema, você poderá aplicar esses comandos e explorar as nuances dos dados. Ao realizar essa análise, é recomendável formular hipóteses sobre possíveis relações, tendências ou padrões nos dados, criando uma lista de questões a serem investigadas e validadas posteriormente.

Convido você a experimentar esses comandos em um conjunto de dados de sua escolha, compartilhar suas descobertas e hipóteses nos comentários e, assim, colaborar com a comunidade interessada em análise de dados. Esse exercício não só fortalece suas habilidades, mas também estimula a troca de ideias e a aprendizagem coletiva. Curta e comente para compartilhar suas experiências e insights, fortalecendo a comunidade de entusiastas e profissionais da área de análise de dados.

Aproveito a oportunidade para te convidar a participar da Comunidade DS avançar ainda mais no desenvolvimento de suas habilidades com Python, através da formação gratuita Data Starter para você aprimorar seus estudos em dados bit.ly/3QitF6O.

--

--