A limpeza de dados significa corrigir dados inválidos no conjunto de dados.
Dados incorretos podem ser:
Analisaremos todos.
Nos próximos capítulos, usaremos o conjunto de dados do arquivo dados8sujos.csv, com 8 linhas:
arq = open('dados8sujos.csv')
dados = arq.read()
print(dados)
Observe:
Importe o Pandas:
import pandas as pd
Carregue o arquivo no dataframe e o imprima com o método to_string() para ver os dados:
df = pd.read_csv('dados8sujos.csv')
print(df.to_string())
Observe que o conjunto de dados contém:
Células vazias podem fornecer um resultado errado na análise dos dados.
Uma maneira de lidar com células com valor "NaN" é remover as linhas correspondentes com o método df.dropna().
Isso geralmente é bom, pois os conjuntos de dados podem ser muito grandes e a remoção de algumas linhas não terá um grande impacto no resultado.
Retorne um novo dataframe sem células vazias:
df = pd.read_csv('dados8sujos.csv')
novo_df = df.dropna()
print(novo_df.to_string())
Por padrão, o método df.dropna() retorna um novo DataFrame e não altera o original.
Para alterar o dataframe original, use o argumento inplace = True.
Exemplo: remova todas as linhas com valores nulos do dataframe:
df = pd.read_csv('dados8sujos.csv')
df.dropna(inplace = True)
print(df.to_string())
O método df.fillna() nos permite substituir células vazias por um valor, evitando a exclusão de linhas inteiras por conta de células vazias.
Substitua os valores nulos pelo número 0.
df = pd.read_csv('dados8sujos.csv')
df.fillna(0, inplace = True)
print(df)
O exemplo acima substitui todas as células vazias em todo o data frame.
Para substituir apenas valores vazios de uma coluna, especifique o nome da coluna para o DataFrame:
Exemplo: substitua os valores NULL nas colunas "Calorias" pelo número 130:
df = pd.read_csv('dados8sujos.csv')
df["Calorias"].fillna(0, inplace = True)
print(df)
Uma maneira comum de substituir células vazias é utilizando os valores médio, mediano ou moda da coluna.
O Pandas usa os métodos mean(), median() e mode() para calcular os respectivos valores para uma coluna especificada.
A média é o valor da soma de todos os valores dividido pela sua quantidade.
Substitua os valores nulos pelo valor do cálculo da média:
df = pd.read_csv('dados8sujos.csv')
x = df["Calorias"].mean()
df["Calorias"].fillna(x, inplace = True)
print(df)
Mediana = o valor no meio, depois de classificar todos os valores em ordem crescente.
Substitua os valores nulos pelo valor do cálculo da mediana:
df = pd.read_csv('dados8sujos.csv')
mediana = df["Calorias"].median()
df["Calorias"].fillna(mediana, inplace = True)
print(df)
A moda é o valor (ou valores) que mais ocorre em uma população ou amostra.
Substitua os valores nulos pelo valor do cálculo da moda da coluna:
df = pd.read_csv('dados8sujos.csv')
x = df["Calorias"].mode()[0]
df["Calorias"].fillna(x, inplace = True)
print(df)
Células com dados de formato incorreto podem dificultar, ou mesmo impossibilitar, a análise dos dados.
Para corrigi-lo, você tem duas opções: remover as linhas ou converter todas as células das colunas para o mesmo formato.
Em nosso dataframe, temos duas células com o formato errado. Confira a linha do índice [5], a coluna 'Data' deve ser uma string que represente uma data:
df = pd.read_csv('dados8sujos.csv')
x = df["Calorias"].mode()[0]
df["Calorias"].fillna(x, inplace = True)
print(df.to_string())
Observer na impressão dos dados do dataframe que o valor da data está como numérico real e o valor não preenchido no índice 5 está como NaN (Not a Number).
df = pd.read_csv('dados8sujos.csv')
print(type(df['Data'][0]))
print(type(df['Data'][5]))
print(df['Data'])
Use o método pd.to_datetime() para converter todas as células da coluna 'Data' formato de texto para o formato de data.
df = pd.read_csv('dados8sujos.csv')
df['Data'] = pd.to_datetime(df['Data'])
print(type(df['Data'][0]))
print(type(df['Data'][5]))
print(df['Data'])
Como você pode ver no resultado, a data na linha [0] foi corrigida, mas a data vazia na linha [5] obteve um valor NaT (Not a Time), ou seja, um valor vazio.
Uma maneira de lidar com valores vazios é simplesmente remover a linha inteira.
O resultado da conversão no exemplo acima nos deu um valor NaT, que pode ser tratado como um valor NULL, e podemos remover a linha usando o dropna()método.
Exemplo: remova as linhas com um valor NULL na coluna "Data".
df = pd.read_csv('dados8sujos.csv')
df['Data'] = pd.to_datetime(df['Data'])
df.dropna(subset=['Data'], inplace = True)
print(df.to_string())
Os dados errados não precisam ser células vazias ou formato errado, pode apenas estar errado, como se alguém registrasse "199" em vez de "1,99".
Às vezes, você pode identificar dados errados observando o conjunto de dados, porque tem uma expectativa do que deveria ser.
Se você der uma olhada em nosso conjunto de dados anterior, verá que na linha [2], a duração é 450, mas para todas as outras linhas a duração está entre 45 e 60.
Pode não estar necessariamente errado, mas levando em consideração que este é o conjunto de dados das sessões de treino de alguém, concluímos com o fato de que essa pessoa não treinou em 450 minutos.
df = pd.read_csv('dados8sujos.csv')
print(df.to_string())
Como podemos corrigir valores errados, como o de "Duracao" na linha [2]?
Uma maneira de corrigir valores errados é substituí-los por outro valor.
Em nosso exemplo, provavelmente é um erro de digitação, e o valor deve ser "45" em vez de "450", e poderíamos inserir "45" na linha [2]:
Exemplo: defina "Duracao" = 45 na linha [2].
df.loc[7, 'Duracao'] = 45
print(df.to_string())
Para conjuntos de dados pequenos, você pode substituir os dados errados um por um, mas não para conjuntos de dados grandes.
Para substituir dados errados por conjuntos de dados maiores, você pode criar algumas regras.
Por exemplo, definir alguns limites para valores legais e substituir quaisquer valores que estejam fora dos limites.
Exemplo: percorra todos os valores na coluna "Duracao". Se o valor for maior que 60, defina-o como 60:
import numpy as np
df = pd.read_csv('dados8sujos.csv')
print('*** ANTES: ',end='\n\n')
print(df.to_string(),end='\n\n')
for x in df.index:
if np.greater(df.loc[x,'Duracao'],60):
df.loc[x,'Duracao'] = 60
print('*** DEPOIS:',end='\n\n')
print(df.to_string())
Outra maneira de lidar com dados errados é remover as linhas que contêm dados errados.
Dessa forma, você não precisa descobrir com o que substituí-los e há uma boa chance de não precisar deles para fazer suas análises.
Exemplo: exclua as linhas em que "Duracao" for maior que 60.
df = pd.read_csv('dados8sujos.csv')
print('ANTES')
print(df.to_string())
for x in df.index:
if df.loc[x, "Duracao"] > 60:
df.drop(x, inplace = True)
print('DEPOIS')
print(df.to_string())
Linhas duplicadas são linhas que foram registradas mais de uma vez.
df = pd.read_csv('dados8sujos.csv')
print(df.to_string())
Ao dar uma olhada em nosso conjunto de dados verificamos que os dados da linhas do índice 8 são os mesmo da linha do índice 8, que está portanto duplicada.
O método duplicated() retorna uma lista com os valores lógicos para cada linha indicando se são duplicadas, sendo True se a linha estiver duplicada e False se não estiver.
dados_dicionario = {
"calorias": [420, 380, 390, 380],
"duracao": [ 50, 40, 45, 40]
}
df_dicionario = pd.DataFrame(dados_dicionario)
print('------ duplicados no dicionário',end='\n\n')
print(df_dicionario.duplicated().to_string(),end='\n\n')
df_arquivo = pd.read_csv('dados8sujos.csv')
print('------ duplicados no arquivo',end='\n\n')
print(df_arquivo.duplicated().to_string())
O método drop_duplicates() retorna a lista sem as linhas duplicadas.
dados_dicionario = {
"calorias": [420, 380, 390, 380],
"duracao": [ 50, 40, 45, 40]
}
#
df_dicionario = pd.DataFrame(dados_dicionario)
print('*** dataframe do dicionário',end='\n\n')
print(df_dicionario.to_string(),end='\n\n')
#
novo_df_ = df_dicionario.drop_duplicates()
print('------ novo dataframe sem duplicados',end='\n\n')
print(novo_df_.to_string())
Com o argumento "inplace = True" o próprio dataframe é alterado e não é retornado um novo dataframe.