Este tutorial vai guiar você por alguns conceitos e etapas básicas de preparação de dados. A preparação de dados é o primeiro passo depois que você tem em mãos qualquer conjunto de dados. É quando você pré-processa dados brutos para um formato que pode ser analisado de forma fácil e precisa. Uma boa preparação de dados permite análises eficientes — ela elimina erros e imprecisões que podem ter surgido na coleta e ajuda a reduzir vieses causados por baixa qualidade dos dados. Não por acaso, boa parte do tempo de um analista é dedicada a essa etapa essencial.
Carregar dados, limpar dados (remover dados desnecessários ou com erro), transformar formatos e reorganizar dados são algumas das ações envolvidas na preparação de dados. Neste tutorial, você vai usar a biblioteca Pandas do Python para preparar dados.
Garanta que você entende conceitos como DataFrame e Series do Pandas, entre outros, porque eles aparecem bastante por aqui. Você pode se aprofundar em pandas no tutorial de Pandas da DataCamp.
Neste tutorial:
Primeiro, você começa com uma rápida introdução ao Pandas — a biblioteca usada aqui.
No caminho, há dicas, truques e links para materiais mais aprofundados caso você queira se aprofundar em algum tópico.
Vamos começar com uma breve introdução ao Pandas...
Pandas
Pandas é uma biblioteca escrita para Python. É muito popular na comunidade de ciência de dados porque oferece estruturas de dados poderosas, expressivas e flexíveis que facilitam a manipulação e a análise — e é gratuita. Além disso, se você tiver um caso de uso específico e novo, pode compartilhá-lo em uma das listas de e-mail de Python ou no repositório do pandas no GitHub — na prática, muitas funcionalidades do pandas surgiram assim, a partir de casos reais.
O primeiro passo da preparação é... conseguir alguns dados. Se você tiver um arquivo .csv, dá para carregá-lo facilmente com a função .read_csv() do pandas. Você pode então digitar:
data = pd.read_csv('path_to_file.csv')
Mas, para este tutorial, vamos trabalhar com alguns DataFrames e Series menores, criados na hora para facilitar o entendimento.
Dados ausentes
Como lidar com dados ausentes
Esse é um problema muito comum no mundo da análise de dados.
Dados ausentes podem surgir por vários motivos: a aplicação ou o usuário não forneceu aquele campo, houve perda na transferência manual, erro de programação etc. Às vezes, entender a causa é essencial, porque isso influencia a estratégia de tratamento. Mas falamos disso mais adiante. Por agora, foque no que fazer quando você tem valores faltantes...
Para dados numéricos, o pandas usa o valor de ponto flutuante NaN (Not a Number) para representar ausências. É um valor único definido na biblioteca Numpy, então vamos importá-la também. O NaN é o marcador padrão de valores ausentes por motivos de desempenho e conveniência. Ele é um valor sentinela, ou seja, um valor de bandeira que pode ser detectado e manipulado facilmente com as funções do pandas.
Vamos brincar com alguns dados...
import numpy as np
# Creating a pandas series
data = pd.Series([0,1,2,3,4,5, np.nan,6,7,8])# To check if and what index in the dataset contains null value
data.isnull()Tecnologia
Acima, usamos a função isnull(), que retorna valores booleanos. True indica que, naquele índice, o dado está ausente (NaN). O oposto é a função notnull().
# To check where the dataset does not contain null value - opposite of isnull()
data.notnull()Tecnologia
Também podemos usar a função dropna() para filtrar e remover os valores nulos e ver apenas os valores não nulos. Porém, o NaN não é realmente deletado do objeto original e continua presente na Series original.
# Will not show the index 6 cause it contains null (NaN) value
data.dropna()Tecnologia
Para realmente "remover" o NaN, você pode armazenar o novo conjunto de dados (sem NaN) em outra variável — assim a Series original não é alterada — ou aplicar o drop inplace. O argumento inplace é false por padrão.
Mas DataFrames podem ser mais complexos e bidimensionais, com linhas e colunas. O pandas também dá conta...
# Creating a dataframe with 4 rows and 4 columns (4*4 matrix)
data_dim = pd.DataFrame([[1,2,3,np.nan],[4,5,np.nan,np.nan],[7,np.nan,np.nan,np.nan],[np.nan,np.nan,np.nan,np.nan]])
data_dim
Tecnologia
0
1
2
3
0
1.0
2.0
3.0
NaN
1
4.0
5.0
NaN
NaN
2
7.0
NaN
NaN
NaN
3
NaN
NaN
NaN
NaN
Agora, digamos que você queira remover apenas as linhas ou colunas que são totalmente nulas, ou apenas aquelas que têm uma certa quantidade de nulos. Veja alguns cenários — lembre que o drop não está sendo feito inplace, então o dataset real não é alterado. Repare nos argumentos passados para dropna() para controlar como descartar os dados ausentes.
# Drop all rows and columns containing NaN value
data_dim.dropna()Tecnologia
0
1
2
3
# Drop all rows and columns containing entirely of NaN value
data_dim.dropna(how ='all')Tecnologia
0
1
2
3
0
1.0
2.0
3.0
NaN
1
4.0
5.0
NaN
NaN
2
7.0
NaN
NaN
NaN
# Drop only columns that contain entirely NaN value# Default is 0 - which signifies rows
data_dim.dropna(axis =1, how ='all')Tecnologia
0
1
2
0
1.0
2.0
3.0
1
4.0
5.0
NaN
2
7.0
NaN
NaN
3
NaN
NaN
NaN
# Drop all columns that have more than 2 NaN values
data_dim.dropna(axis =1, thresh =2)Tecnologia
0
1
0
1.0
2.0
1
4.0
5.0
2
7.0
NaN
3
NaN
NaN
# Drop all rows that have more than 2 NaN values
data_dim.dropna(thresh =2)Tecnologia
0
1
2
3
0
1.0
2.0
3.0
NaN
1
4.0
5.0
NaN
NaN
Agora você já sabe identificar e remover valores ausentes — seja para visualizar o resultado, seja para fazer a exclusão inplace. Em muitos casos, simplesmente descartar nulos não é viável; você pode preferir preencher os dados faltantes com outro valor. Vamos ver como fazer isso...
Preenchendo dados ausentes
Para substituir — ou melhor, "preencher" — dados nulos, use a função fillna(). Por exemplo, vamos usar o mesmo dataset de cima e preencher os NaNs com 0.
# Check what the dataset looks like again
data_dim
Tecnologia
0
1
2
3
0
1.0
2.0
3.0
NaN
1
4.0
5.0
NaN
NaN
2
7.0
NaN
NaN
NaN
3
NaN
NaN
NaN
NaN
# Fill the NaN values with 0
data_dim_fill = data_dim.fillna(0)
data_dim_fill
Tecnologia
0
1
2
3
0
1.0
2.0
3.0
0.0
1
4.0
5.0
0.0
0.0
2
7.0
0.0
0.0
0.0
3
0.0
0.0
0.0
0.0
Assim como em dropna(), você pode fazer outras coisas dependendo dos argumentos. E lembrete: passar inplace = True altera o dataset original.
# Pass a dictionary to use differnt values for each column
data_dim_fill = data_dim.fillna({0:0,1:8,2:9,3:10})
data_dim_fill
Tecnologia
0
1
2
3
0
1.0
2.0
3.0
10.0
1
4.0
5.0
9.0
10.0
2
7.0
8.0
9.0
10.0
3
0.0
8.0
9.0
10.0
Você pode passar o argumento method para fillna() e propagar automaticamente valores não nulos para frente (ffill ou pad) ou para trás (bfill ou backfill).
# Pass method to determine how to fill-up the column - forward here
data_dim_fill = data_dim.fillna(method='ffill')
data_dim_fill
Tecnologia
0
1
2
3
0
1.0
2.0
3.0
NaN
1
4.0
5.0
3.0
NaN
2
7.0
5.0
3.0
NaN
3
7.0
5.0
3.0
NaN
Você também pode limitar o número de preenchimentos. Por exemplo, preencher apenas dois valores em cada coluna... Além disso, se você passar axis = 1, o preenchimento ocorre ao longo da linha.
# Pass method to determine how to fill-up the column - forward here
data_dim_fill = data_dim.fillna(method='ffill', limit =2)
data_dim_fill
Tecnologia
0
1
2
3
0
1.0
2.0
3.0
NaN
1
4.0
5.0
3.0
NaN
2
7.0
5.0
3.0
NaN
3
7.0
5.0
NaN
NaN
# Pass method to determine how to fill-up the row - forward here
data_dim_fill = data_dim.fillna(axis =1, method='ffill')
data_dim_fill
Tecnologia
0
1
2
3
0
1.0
2.0
3.0
3.0
1
4.0
5.0
5.0
5.0
2
7.0
7.0
7.0
7.0
3
NaN
NaN
NaN
NaN
Com algum entendimento do seu dado e do seu caso de uso, dá para usar fillna() de várias formas além de números fixos. Você pode, por exemplo, preencher com a média usando mean() ou a mediana com median()...
# Fill the NaN value with mean values in the corresponding column
data_dim_fill = data_dim.fillna(data_dim.mean())
data_dim_fill
Tecnologia
0
1
2
3
0
1.0
2.0
3.0
NaN
1
4.0
5.0
3.0
NaN
2
7.0
3.5
3.0
NaN
3
4.0
3.5
3.0
NaN
Transformação de dados
Substituindo valores
Até aqui, trabalhamos apenas com ausências (NaN), mas pode haver situações em que você queira trocar um valor não nulo por outro. Ou talvez um valor ausente foi registrado como um número arbitrário e, por isso, precisa ser tratado como NaN e não como número. É aí que a função replace() ajuda...
Vamos criar um dataset diferente desta vez.
data = pd.Series([1,2,-99,4,5,-99,7,8,-99])
data
Tecnologia
Você não verá mais o -99, pois ele foi substituído por NaN e, por isso, não aparece. Da mesma forma, dá para passar múltiplos valores para substituir. Para isso, vamos criar outra Series, concatená-la com a original e aplicar a substituição múltipla.
Concatenando Series do pandas
Para isso, usamos a função concat() do pandas. Para reiniciar a indexação após a concatenação, passe o argumento ignore_index = True.
# Create a new Series
new_data = pd.Series([-100,11,12,13])
combined_series = pd.concat([data, new_data], ignore_index =True)
combined_series
Tecnologia
# Argument passed can also be a dictionary with separate values
data_replaced = combined_series.replace({-99: np.nan,-100:0})# Same as: new_data.replace([-99, -100], [np.nan, 0])
data_replaced
Tecnologia
Em algumas situações, você pode querer adicionar mais contexto ao que já tem com base em alguma lógica. Dá para fazer isso com mapeamentos e a combinação de funções. A lógica pode ficar mais complexa, mas vamos entender pelo exemplo.
Suponha que você tenha um DataFrame com números mapeados às suas palavras em inglês.
Agora, você quer adicionar outra coluna indicando múltiplos de dois com 'yes' e o restante com 'no'. Você pode escrever um mapeamento das palavras em inglês para 'yes' ou 'no'.
Em seguida, chame a função map para adicionar a coluna quando o valor de English for múltiplo de 2. E o que é preenchido nas outras linhas que não são múltiplos? Vamos ver...
As outras linhas ficam com NaN, e você já sabe como tratar valores ausentes. Este foi um exemplo simples, mas serve de inspiração para usar map em outros casos.
Discretização — função cut
Às vezes, você pode querer categorizar com base em alguma lógica e colocar os dados em faixas (bins) para análise. Você pode usar cut() para isso. Por exemplo, vamos criar um conjunto com 30 números aleatórios entre 1 e 100.
import random
data = random.sample(range(1,101),30)# dataTecnologia
Digamos que queremos categorizar em baldes definidos por nós: números entre 1–25, depois 25–35, 40–60, 60–80 e o restante. Então definimos os intervalos...
Depois usamos a função cut.
# Defining the starting value for each bucket
bucket =[1,25,35,60,80,100]
cut_data = pd.cut(data, bucket)
cut_data
Tecnologia
cut() é muito útil, e dá para fazer bem mais com ela. Vale a pena conferir a documentação do Pandas para saber mais.
Variáveis dummies e one-hot encodings
Este tópico é especialmente útil quando você precisa converter dados categóricos em valores numéricos para usar em modelos de análise. É muito usado em modelagem de machine learning, onde o conceito de one-hot encoding é famoso. Em termos técnicos: one-hot encoding é o processo de converter valores categóricos em um vetor numérico 1-dimensional.
Uma forma de fazer isso no pandas é com get_dummies(). Se uma coluna do seu DataFrame tem 'n' valores distintos, a função cria uma matriz com 'n' colunas contendo 1s e 0s. Vamos ver um exemplo para fixar o conceito...
# Creating a DataFrame consiting individual characters in the list
data = pd.Series(list('abcdababcdabcd'))
data
Tecnologia
0 a
1 b
2 c
3 d
4 a
5 b
6 a
7 b
8 c
9 d
10 a
11 b
12 c
13 d
dtype: object
Tecnologia
Agora, digamos que você quer vetores individuais indicando a presença de cada caractere para alimentar uma função.
Algo como: para 'a' = [1,0,0,0,1,0,1,0,0,0,1,0,0,0], em que 1 marca onde existe 'a' e 0 onde não existe. Com get_dummies(), a tarefa fica simples.
Este é um exemplo simples para começar. Em aplicações reais, um mesmo item pode pertencer a várias categorias ao mesmo tempo, então você vai precisar de técnicas mais sofisticadas. E, para volumes muito grandes, essa função pode não ser a mais eficiente em velocidade. O artigo da DataCamp Handling Categorical Data in Python aprofunda esses casos.
E agora?
Você chegou ao fim do tutorial e aprendeu ferramentas básicas para dar o primeiro passo na sua jornada de análise de dados. Outras habilidades úteis na preparação de dados incluem detectar e filtrar outliers e, se o dataset for muito grande, começar com amostragem aleatória. Mas esses já são tópicos amplos por si só e difíceis de generalizar.
Casos de uso do mundo real costumam ser mais complexos e podem exigir soluções próprias, mas a ideia é começar pequeno, aprender no caminho, explorar mais e colocar a mão na massa com diferentes datasets! Não deixe de conferir o curso Cleaning Data in Python da DataCamp para aprender mais ferramentas e truques. No final, você ainda vai trabalhar com um dataset bagunçado, real, da Gapminder Foundation. Bora começar!
Explore a análise de dados com Python. Os DataFrames do Pandas facilitam a manipulação de seus dados, desde a seleção ou substituição de colunas e índices até a remodelagem dos dados.
A importação de dados é a primeira etapa de qualquer projeto de ciência de dados. Saiba por que os cientistas de dados atuais preferem a função read_csv() do pandas para fazer isso.
Use o Python Pandas e selecione colunas de DataFrames. Siga nosso tutorial com exemplos de código e aprenda diferentes maneiras de selecionar seus dados hoje mesmo!
Mergulhe na ciência de dados com Python para analisar e visualizar seus dados de forma eficaz. Não precisa ter experiência ou conhecimento em programação.
Este tutorial vai guiar você por alguns conceitos e etapas básicas de preparação de dados. A preparação de dados é o primeiro passo depois que você tem em mãos qualquer conjunto de dados. É quando você pré-processa dados brutos para um formato que pode ser analisado de forma fácil e precisa. Uma boa preparação de dados permite análises eficientes — ela elimina erros e imprecisões que podem ter surgido na coleta e ajuda a reduzir vieses causados por baixa qualidade dos dados. Não por acaso, boa parte do tempo de um analista é dedicada a essa etapa essencial.
Carregar dados, limpar dados (remover dados desnecessários ou com erro), transformar formatos e reorganizar dados são algumas das ações envolvidas na preparação de dados. Neste tutorial, você vai usar a biblioteca Pandas do Python para preparar dados.
Garanta que você entende conceitos como DataFrame e Series do Pandas, entre outros, porque eles aparecem bastante por aqui. Você pode se aprofundar em pandas no tutorial de Pandas da DataCamp.
Neste tutorial:
No caminho, há dicas, truques e links para materiais mais aprofundados caso você queira se aprofundar em algum tópico.
Vamos começar com uma breve introdução ao Pandas...
Pandas
Pandas é uma biblioteca escrita para Python. É muito popular na comunidade de ciência de dados porque oferece estruturas de dados poderosas, expressivas e flexíveis que facilitam a manipulação e a análise — e é gratuita. Além disso, se você tiver um caso de uso específico e novo, pode compartilhá-lo em uma das listas de e-mail de Python ou no repositório do pandas no GitHub — na prática, muitas funcionalidades do pandas surgiram assim, a partir de casos reais.
Para uma ótima introdução a pandas, confira o curso Pandas Foundation da DataCamp. Ele é super interativo e o primeiro capítulo é grátis!
Para usar a biblioteca pandas, primeiro importe-a. Digite no seu console Python:
Carregando dados
O primeiro passo da preparação é... conseguir alguns dados. Se você tiver um arquivo .csv, dá para carregá-lo facilmente com a função
.read_csv()do pandas. Você pode então digitar:data = pd.read_csv('path_to_file.csv')
Mas, para este tutorial, vamos trabalhar com alguns DataFrames e Series menores, criados na hora para facilitar o entendimento.
Dados ausentes
Como lidar com dados ausentes
Esse é um problema muito comum no mundo da análise de dados.
Fonte
Dados ausentes podem surgir por vários motivos: a aplicação ou o usuário não forneceu aquele campo, houve perda na transferência manual, erro de programação etc. Às vezes, entender a causa é essencial, porque isso influencia a estratégia de tratamento. Mas falamos disso mais adiante. Por agora, foque no que fazer quando você tem valores faltantes...
Para dados numéricos, o pandas usa o valor de ponto flutuante NaN (Not a Number) para representar ausências. É um valor único definido na biblioteca Numpy, então vamos importá-la também. O NaN é o marcador padrão de valores ausentes por motivos de desempenho e conveniência. Ele é um valor sentinela, ou seja, um valor de bandeira que pode ser detectado e manipulado facilmente com as funções do pandas.
Vamos brincar com alguns dados...
Acima, usamos a função
isnull(), que retorna valores booleanos. True indica que, naquele índice, o dado está ausente (NaN). O oposto é a funçãonotnull().Também podemos usar a função
dropna()para filtrar e remover os valores nulos e ver apenas os valores não nulos. Porém, o NaN não é realmente deletado do objeto original e continua presente na Series original.Para realmente "remover" o NaN, você pode armazenar o novo conjunto de dados (sem NaN) em outra variável — assim a Series original não é alterada — ou aplicar o drop inplace. O argumento inplace é false por padrão.
Mas DataFrames podem ser mais complexos e bidimensionais, com linhas e colunas. O pandas também dá conta...
Agora, digamos que você queira remover apenas as linhas ou colunas que são totalmente nulas, ou apenas aquelas que têm uma certa quantidade de nulos. Veja alguns cenários — lembre que o drop não está sendo feito inplace, então o dataset real não é alterado. Repare nos argumentos passados para
dropna()para controlar como descartar os dados ausentes.Agora você já sabe identificar e remover valores ausentes — seja para visualizar o resultado, seja para fazer a exclusão inplace. Em muitos casos, simplesmente descartar nulos não é viável; você pode preferir preencher os dados faltantes com outro valor. Vamos ver como fazer isso...
Preenchendo dados ausentes
Para substituir — ou melhor, "preencher" — dados nulos, use a função
fillna(). Por exemplo, vamos usar o mesmo dataset de cima e preencher os NaNs com 0.Assim como em
dropna(), você pode fazer outras coisas dependendo dos argumentos. E lembrete: passarinplace = Truealtera o dataset original.Você pode passar o argumento method para
fillna()e propagar automaticamente valores não nulos para frente (ffill ou pad) ou para trás (bfill ou backfill).Você também pode limitar o número de preenchimentos. Por exemplo, preencher apenas dois valores em cada coluna... Além disso, se você passar axis = 1, o preenchimento ocorre ao longo da linha.
Com algum entendimento do seu dado e do seu caso de uso, dá para usar
fillna()de várias formas além de números fixos. Você pode, por exemplo, preencher com a média usandomean()ou a mediana commedian()...Transformação de dados
Substituindo valores
Até aqui, trabalhamos apenas com ausências (NaN), mas pode haver situações em que você queira trocar um valor não nulo por outro. Ou talvez um valor ausente foi registrado como um número arbitrário e, por isso, precisa ser tratado como NaN e não como número. É aí que a função
replace()ajuda...Vamos criar um dataset diferente desta vez.
Você não verá mais o -99, pois ele foi substituído por NaN e, por isso, não aparece. Da mesma forma, dá para passar múltiplos valores para substituir. Para isso, vamos criar outra Series, concatená-la com a original e aplicar a substituição múltipla.
Concatenando Series do pandas
Para isso, usamos a função
concat()do pandas. Para reiniciar a indexação após a concatenação, passe o argumentoignore_index = True.Adicionando conhecimento — função map
Em algumas situações, você pode querer adicionar mais contexto ao que já tem com base em alguma lógica. Dá para fazer isso com mapeamentos e a combinação de funções. A lógica pode ficar mais complexa, mas vamos entender pelo exemplo.
Suponha que você tenha um DataFrame com números mapeados às suas palavras em inglês.
Agora, você quer adicionar outra coluna indicando múltiplos de dois com 'yes' e o restante com 'no'. Você pode escrever um mapeamento das palavras em inglês para 'yes' ou 'no'.
Em seguida, chame a função map para adicionar a coluna quando o valor de English for múltiplo de 2. E o que é preenchido nas outras linhas que não são múltiplos? Vamos ver...
As outras linhas ficam com NaN, e você já sabe como tratar valores ausentes. Este foi um exemplo simples, mas serve de inspiração para usar map em outros casos.
Discretização — função cut
Às vezes, você pode querer categorizar com base em alguma lógica e colocar os dados em faixas (bins) para análise. Você pode usar
cut()para isso. Por exemplo, vamos criar um conjunto com 30 números aleatórios entre 1 e 100.Digamos que queremos categorizar em baldes definidos por nós: números entre 1–25, depois 25–35, 40–60, 60–80 e o restante. Então definimos os intervalos...
Depois usamos a função cut.
cut()é muito útil, e dá para fazer bem mais com ela. Vale a pena conferir a documentação do Pandas para saber mais.Variáveis dummies e one-hot encodings
Este tópico é especialmente útil quando você precisa converter dados categóricos em valores numéricos para usar em modelos de análise. É muito usado em modelagem de machine learning, onde o conceito de one-hot encoding é famoso. Em termos técnicos: one-hot encoding é o processo de converter valores categóricos em um vetor numérico 1-dimensional.
Uma forma de fazer isso no pandas é com
get_dummies(). Se uma coluna do seu DataFrame tem 'n' valores distintos, a função cria uma matriz com 'n' colunas contendo 1s e 0s. Vamos ver um exemplo para fixar o conceito...Agora, digamos que você quer vetores individuais indicando a presença de cada caractere para alimentar uma função.
Algo como: para 'a' = [1,0,0,0,1,0,1,0,0,0,1,0,0,0], em que 1 marca onde existe 'a' e 0 onde não existe. Com
get_dummies(), a tarefa fica simples.Este é um exemplo simples para começar. Em aplicações reais, um mesmo item pode pertencer a várias categorias ao mesmo tempo, então você vai precisar de técnicas mais sofisticadas. E, para volumes muito grandes, essa função pode não ser a mais eficiente em velocidade. O artigo da DataCamp Handling Categorical Data in Python aprofunda esses casos.
E agora?
Você chegou ao fim do tutorial e aprendeu ferramentas básicas para dar o primeiro passo na sua jornada de análise de dados. Outras habilidades úteis na preparação de dados incluem detectar e filtrar outliers e, se o dataset for muito grande, começar com amostragem aleatória. Mas esses já são tópicos amplos por si só e difíceis de generalizar.
Casos de uso do mundo real costumam ser mais complexos e podem exigir soluções próprias, mas a ideia é começar pequeno, aprender no caminho, explorar mais e colocar a mão na massa com diferentes datasets! Não deixe de conferir o curso Cleaning Data in Python da DataCamp para aprender mais ferramentas e truques. No final, você ainda vai trabalhar com um dataset bagunçado, real, da Gapminder Foundation. Bora começar!