19 KiB
Trabalhar com Dados: Preparação de Dados
![]() |
|---|
| Preparação de Dados - Sketchnote por @nitya |
Questionário Pré-Aula
Dependendo da sua origem, os dados brutos podem conter algumas inconsistências que causarão desafios na análise e modelagem. Em outras palavras, esses dados podem ser categorizados como "sujos" e precisarão ser limpos. Esta lição foca em técnicas para limpar e transformar os dados, lidando com desafios como dados ausentes, imprecisos ou incompletos. Os tópicos abordados nesta lição utilizarão Python e a biblioteca Pandas e serão demonstrados no notebook dentro deste diretório.
A importância de limpar os dados
-
Facilidade de uso e reutilização: Quando os dados estão devidamente organizados e normalizados, é mais fácil pesquisá-los, utilizá-los e compartilhá-los com outros.
-
Consistência: A ciência de dados frequentemente exige trabalhar com mais de um conjunto de dados, onde conjuntos de dados de diferentes fontes precisam ser combinados. Garantir que cada conjunto de dados individual tenha uma padronização comum assegura que os dados ainda sejam úteis quando todos forem mesclados em um único conjunto.
-
Precisão do modelo: Dados que foram limpos melhoram a precisão dos modelos que dependem deles.
Objetivos e estratégias comuns de limpeza
-
Explorar um conjunto de dados: A exploração de dados, que será abordada em uma lição posterior, pode ajudá-lo a identificar dados que precisam ser limpos. Observar visualmente os valores dentro de um conjunto de dados pode estabelecer expectativas sobre como o restante será, ou fornecer uma ideia dos problemas que podem ser resolvidos. A exploração pode envolver consultas básicas, visualizações e amostragem.
-
Formatação: Dependendo da origem, os dados podem ter inconsistências na forma como são apresentados. Isso pode causar problemas na pesquisa e representação dos valores, onde eles aparecem no conjunto de dados, mas não são devidamente representados em visualizações ou resultados de consultas. Problemas comuns de formatação incluem resolver espaços em branco, datas e tipos de dados. Resolver questões de formatação geralmente cabe às pessoas que estão utilizando os dados. Por exemplo, os padrões sobre como datas e números são apresentados podem variar de país para país.
-
Duplicações: Dados que aparecem mais de uma vez podem produzir resultados imprecisos e geralmente devem ser removidos. Isso pode ocorrer frequentemente ao combinar dois ou mais conjuntos de dados. No entanto, há casos em que duplicações em conjuntos de dados combinados contêm informações adicionais que podem precisar ser preservadas.
-
Dados ausentes: Dados ausentes podem causar imprecisões, bem como resultados fracos ou enviesados. Às vezes, isso pode ser resolvido com um "recarregamento" dos dados, preenchendo os valores ausentes com cálculos e código, como Python, ou simplesmente removendo o valor e os dados correspondentes. Existem várias razões para os dados estarem ausentes, e as ações tomadas para resolver esses valores ausentes podem depender de como e por que eles desapareceram.
Explorando informações de DataFrames
Objetivo de aprendizagem: Ao final desta subseção, você deve estar confortável em encontrar informações gerais sobre os dados armazenados em DataFrames do pandas.
Depois de carregar seus dados no pandas, é provável que eles estejam em um DataFrame (consulte a lição anterior para uma visão geral detalhada). No entanto, se o conjunto de dados no seu DataFrame tiver 60.000 linhas e 400 colunas, como começar a entender com o que você está lidando? Felizmente, o pandas fornece ferramentas convenientes para rapidamente visualizar informações gerais sobre um DataFrame, além das primeiras e últimas linhas.
Para explorar essa funcionalidade, importaremos a biblioteca Python scikit-learn e usaremos um conjunto de dados icônico: o conjunto de dados Iris.
import pandas as pd
from sklearn.datasets import load_iris
iris = load_iris()
iris_df = pd.DataFrame(data=iris['data'], columns=iris['feature_names'])
| sepal length (cm) | sepal width (cm) | petal length (cm) | petal width (cm) | |
|---|---|---|---|---|
| 0 | 5.1 | 3.5 | 1.4 | 0.2 |
| 1 | 4.9 | 3.0 | 1.4 | 0.2 |
| 2 | 4.7 | 3.2 | 1.3 | 0.2 |
| 3 | 4.6 | 3.1 | 1.5 | 0.2 |
| 4 | 5.0 | 3.6 | 1.4 | 0.2 |
- DataFrame.info: Para começar, o método
info()é usado para imprimir um resumo do conteúdo presente em umDataFrame. Vamos dar uma olhada neste conjunto de dados para ver o que temos:
iris_df.info()
RangeIndex: 150 entries, 0 to 149
Data columns (total 4 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 sepal length (cm) 150 non-null float64
1 sepal width (cm) 150 non-null float64
2 petal length (cm) 150 non-null float64
3 petal width (cm) 150 non-null float64
dtypes: float64(4)
memory usage: 4.8 KB
A partir disso, sabemos que o conjunto de dados Iris tem 150 entradas em quatro colunas, sem entradas nulas. Todos os dados estão armazenados como números de ponto flutuante de 64 bits.
- DataFrame.head(): Em seguida, para verificar o conteúdo real do
DataFrame, usamos o métodohead(). Vamos ver como as primeiras linhas do nossoiris_dfse parecem:
iris_df.head()
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm)
0 5.1 3.5 1.4 0.2
1 4.9 3.0 1.4 0.2
2 4.7 3.2 1.3 0.2
3 4.6 3.1 1.5 0.2
4 5.0 3.6 1.4 0.2
- DataFrame.tail(): Por outro lado, para verificar as últimas linhas do
DataFrame, usamos o métodotail():
iris_df.tail()
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm)
145 6.7 3.0 5.2 2.3
146 6.3 2.5 5.0 1.9
147 6.5 3.0 5.2 2.0
148 6.2 3.4 5.4 2.3
149 5.9 3.0 5.1 1.8
Conclusão: Apenas observando os metadados sobre as informações em um DataFrame ou os primeiros e últimos valores em um, você pode obter uma ideia imediata sobre o tamanho, a forma e o conteúdo dos dados com os quais está lidando.
Lidando com Dados Ausentes
Objetivo de aprendizagem: Ao final desta subseção, você deve saber como substituir ou remover valores nulos de DataFrames.
Na maioria das vezes, os conjuntos de dados que você deseja usar (ou precisa usar) têm valores ausentes. A forma como os dados ausentes são tratados traz consigo sutis compensações que podem afetar sua análise final e os resultados no mundo real.
O pandas lida com valores ausentes de duas maneiras. A primeira, que você já viu em seções anteriores, é o NaN, ou Not a Number. Este é, na verdade, um valor especial que faz parte da especificação de ponto flutuante IEEE e é usado apenas para indicar valores de ponto flutuante ausentes.
Para valores ausentes que não sejam de ponto flutuante, o pandas usa o objeto None do Python. Embora possa parecer confuso encontrar dois tipos diferentes de valores que indicam essencialmente a mesma coisa, há razões programáticas sólidas para essa escolha de design e, na prática, isso permite que o pandas ofereça um bom compromisso para a grande maioria dos casos. Ainda assim, tanto None quanto NaN têm restrições que você precisa ter em mente em relação a como podem ser usados.
Confira mais sobre NaN e None no notebook!
- Detectando valores nulos: No
pandas, os métodosisnull()enotnull()são suas principais ferramentas para detectar dados nulos. Ambos retornam máscaras booleanas sobre seus dados. Usaremosnumpypara valoresNaN:
import numpy as np
example1 = pd.Series([0, np.nan, '', None])
example1.isnull()
0 False
1 True
2 False
3 True
dtype: bool
Observe atentamente a saída. Alguma coisa te surpreende? Embora 0 seja um nulo aritmético, ele ainda é um inteiro válido e o pandas o trata como tal. '' é um pouco mais sutil. Embora o tenhamos usado na Seção 1 para representar um valor de string vazio, ele ainda é um objeto string e não uma representação de nulo para o pandas.
Agora, vamos inverter isso e usar esses métodos de uma maneira mais prática. Você pode usar máscaras booleanas diretamente como um índice de Series ou DataFrame, o que pode ser útil ao tentar trabalhar com valores isolados ausentes (ou presentes).
Conclusão: Tanto os métodos
isnull()quantonotnull()produzem resultados semelhantes quando usados emDataFrames: eles mostram os resultados e o índice desses resultados, o que será extremamente útil ao lidar com seus dados.
- Removendo valores nulos: Além de identificar valores ausentes, o pandas fornece um meio conveniente para remover valores nulos de
SerieseDataFrames. (Particularmente em grandes conjuntos de dados, muitas vezes é mais aconselhável simplesmente remover valores ausentes [NA] da sua análise do que lidar com eles de outras maneiras.) Para ver isso em ação, vamos voltar aoexample1:
example1 = example1.dropna()
example1
0 0
2
dtype: object
Observe que isso deve se parecer com sua saída de example3[example3.notnull()]. A diferença aqui é que, em vez de apenas indexar os valores mascarados, dropna removeu esses valores ausentes da Series example1.
Como os DataFrames têm duas dimensões, eles oferecem mais opções para remover dados.
example2 = pd.DataFrame([[1, np.nan, 7],
[2, 5, 8],
[np.nan, 6, 9]])
example2
| 0 | 1 | 2 | |
|---|---|---|---|
| 0 | 1.0 | NaN | 7 |
| 1 | 2.0 | 5.0 | 8 |
| 2 | NaN | 6.0 | 9 |
(Você notou que o pandas converteu duas das colunas para floats para acomodar os NaNs?)
Você não pode remover um único valor de um DataFrame, então precisa remover linhas ou colunas inteiras. Dependendo do que você está fazendo, pode querer fazer uma coisa ou outra, e o pandas oferece opções para ambas. Como na ciência de dados as colunas geralmente representam variáveis e as linhas representam observações, é mais provável que você remova linhas de dados; a configuração padrão para dropna() é remover todas as linhas que contêm quaisquer valores nulos:
example2.dropna()
0 1 2
1 2.0 5.0 8
Se necessário, você pode remover valores NA de colunas. Use axis=1 para fazer isso:
example2.dropna(axis='columns')
2
0 7
1 8
2 9
Observe que isso pode remover muitos dados que você pode querer manter, particularmente em conjuntos de dados menores. E se você quiser apenas remover linhas ou colunas que contenham vários ou até mesmo todos os valores nulos? Você especifica essas configurações em dropna com os parâmetros how e thresh.
Por padrão, how='any' (se quiser verificar por si mesmo ou ver quais outros parâmetros o método possui, execute example4.dropna? em uma célula de código). Você poderia, alternativamente, especificar how='all' para remover apenas linhas ou colunas que contenham todos os valores nulos. Vamos expandir nosso exemplo de DataFrame para ver isso em ação.
example2[3] = np.nan
example2
| 0 | 1 | 2 | 3 | |
|---|---|---|---|---|
| 0 | 1.0 | NaN | 7 | NaN |
| 1 | 2.0 | 5.0 | 8 | NaN |
| 2 | NaN | 6.0 | 9 | NaN |
O parâmetro thresh oferece um controle mais refinado: você define o número de valores não nulos que uma linha ou coluna precisa ter para ser mantida:
example2.dropna(axis='rows', thresh=3)
0 1 2 3
1 2.0 5.0 8 NaN
Aqui, a primeira e a última linha foram removidas, porque contêm apenas dois valores não nulos.
- Preenchendo valores nulos: Dependendo do seu conjunto de dados, às vezes pode fazer mais sentido preencher valores nulos com valores válidos em vez de removê-los. Você poderia usar
isnullpara fazer isso no lugar, mas isso pode ser trabalhoso, especialmente se você tiver muitos valores para preencher. Como essa é uma tarefa comum na ciência de dados, o pandas fornecefillna, que retorna uma cópia daSeriesouDataFramecom os valores ausentes substituídos por um de sua escolha. Vamos criar outraSeriesde exemplo para ver como isso funciona na prática.
example3 = pd.Series([1, np.nan, 2, None, 3], index=list('abcde'))
example3
a 1.0
b NaN
c 2.0
d NaN
e 3.0
dtype: float64
Você pode preencher todas as entradas nulas com um único valor, como 0:
example3.fillna(0)
a 1.0
b 0.0
c 2.0
d 0.0
e 3.0
dtype: float64
Você pode preencher para frente valores nulos, ou seja, usar o último valor válido para preencher um nulo:
example3.fillna(method='ffill')
a 1.0
b 1.0
c 2.0
d 2.0
e 3.0
dtype: float64
Você também pode preencher para trás para propagar o próximo valor válido para trás e preencher um nulo:
example3.fillna(method='bfill')
a 1.0
b 2.0
c 2.0
d 3.0
e 3.0
dtype: float64
Como você pode imaginar, isso funciona da mesma forma com DataFrames, mas você também pode especificar um axis ao longo do qual preencher valores nulos. Usando novamente o example2:
example2.fillna(method='ffill', axis=1)
0 1 2 3
0 1.0 1.0 7.0 7.0
1 2.0 5.0 8.0 8.0
2 NaN 6.0 9.0 9.0
Observe que, quando um valor anterior não está disponível para preenchimento para frente, o valor nulo permanece.
Conclusão: Existem várias formas de lidar com valores em falta nos seus conjuntos de dados. A estratégia específica que utiliza (removê-los, substituí-los ou até mesmo como os substitui) deve ser ditada pelas particularidades desses dados. Desenvolverá uma melhor noção de como tratar valores em falta à medida que lida e interage com conjuntos de dados.
Remover dados duplicados
Objetivo de aprendizagem: No final desta subseção, deverá sentir-se confortável em identificar e remover valores duplicados de DataFrames.
Além de dados em falta, encontrará frequentemente dados duplicados em conjuntos de dados do mundo real. Felizmente, o pandas oferece uma forma simples de detetar e remover entradas duplicadas.
- Identificar duplicados:
duplicated: Pode facilmente identificar valores duplicados utilizando o métododuplicatedno pandas, que devolve uma máscara Booleana indicando se uma entrada numDataFrameé duplicada de uma anterior. Vamos criar outro exemplo deDataFramepara ver isto em ação.
example4 = pd.DataFrame({'letters': ['A','B'] * 2 + ['B'],
'numbers': [1, 2, 1, 3, 3]})
example4
| letters | numbers | |
|---|---|---|
| 0 | A | 1 |
| 1 | B | 2 |
| 2 | A | 1 |
| 3 | B | 3 |
| 4 | B | 3 |
example4.duplicated()
0 False
1 False
2 True
3 False
4 True
dtype: bool
- Remover duplicados:
drop_duplicates: devolve simplesmente uma cópia dos dados para os quais todos os valoresduplicatedsãoFalse:
example4.drop_duplicates()
letters numbers
0 A 1
1 B 2
3 B 3
Tanto duplicated como drop_duplicates consideram por padrão todas as colunas, mas pode especificar que examinem apenas um subconjunto de colunas no seu DataFrame:
example4.drop_duplicates(['letters'])
letters numbers
0 A 1
1 B 2
Conclusão: Remover dados duplicados é uma parte essencial de quase todos os projetos de ciência de dados. Dados duplicados podem alterar os resultados das suas análises e fornecer resultados imprecisos!
🚀 Desafio
Todo o material discutido está disponível como um Jupyter Notebook. Além disso, há exercícios presentes após cada seção, experimente-os!
Questionário pós-aula
Revisão e Estudo Individual
Existem várias formas de descobrir e abordar a preparação dos seus dados para análise e modelação, e a limpeza dos dados é um passo importante que requer uma experiência prática. Experimente estes desafios do Kaggle para explorar técnicas que esta lição não abordou.
Tarefa
Avaliar Dados de um Formulário
Aviso Legal:
Este documento foi traduzido utilizando o serviço de tradução por IA Co-op Translator. Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original no seu idioma nativo deve ser considerado a fonte oficial. Para informações críticas, recomenda-se uma tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas resultantes do uso desta tradução.
