An?lise de dados com Python
April 26, 2019
1
Introdução a análise de dados
Novidades:
O tratamento de campos do tipo Data Como renomear colunas
Tratar arquivo em lote (usando biblioteca glob) Agrupamento de dados (Resampling)
Conversão de arquivos de codificação ISO8859-15 para a codificação UTF-8 Conversão de arquivos do Windows para Linux
O uso do seaborn
1.1 O regime de chuvas em Ouro Branco-MG 1.2 A coleta de dados
As estações 2043052 (Ouro Branco), 2043101 (Lobo leite), 2043100 (Congonhas, Dom Oscar), 2043099 (Estação Congonhas Alto do Cruzeiro), 2043013 (Congonhas), 2043102 (Estação Con-gonhas, Joaquim Murtinho), 2043104 (Estação Conselheiro Lafaiete Gagé) estão localizadas em uma área, que possivelmente compartilham o mesmo regime de chuvas que a Cidade de Ouro Branco. No entanto, não é possível verificar essa informação, pois dessas seis estações apenas a estação 2043052 (Ouro Branco) e a estação 2043013 (Congonhas) tem dados disponíveis.
A 2043052 (Figura 1, apontada pelo número 1) fica localizada na base da Serra do Ouro Branco e é gerida pela “Aço Minas”, que iniciou a coleta de dados em maio de 1977 por pluviômetro. A telemetria foi iniciada em 2006 (Figura 1, apontada pelo número 1).
A estação 2043013 (Figura 1, apontada pelo número 2) é gerida pela CPRM/ANA Plu-viométrica, é uma Estação baseada em Linígrafo, Latitude -20,521944, Longitude -43,830000, que iniciou a coleta de addos em maio de 1941 por pluviômetro até 01/08/2012, quando passou a utilizar Telemetria (cujos daos não estão disponíveis).
Objetivos:
Geral: Verificar se houve alteração significativa no regime de chuvas de Ouro Branco desde 1977.
Específicos: Verificar se há dados disponíveis e confiáveis para o período (1977 a 2019); e veri-ficar a Confiabilidade dos dados.
Foram adquiridos os dados da Agência Naconal de Águas (ANA) sobre Chuvas das estações 2043052 e 2043013, no formato de arquivos CSV.
Observação: Essa análise é uma demonstração. Portanto, por razões didáticas, a simpliciade e o metódo computacional foram adotados como requisitos.
In [ ]: import matplotlib.pyplot as plt import numpy as np import pandas as pd import math import glob # Arquivos de dados #chuvas_C_02043052.csv #chuvas_C_02043013.csv
1.3 Conversão de arquivos de codificação ISO8859-15 para a codificação UTF-8
1.3.1 Conversão de arquivos do Windows para Linux
Primeiro vamos ver os arqivos e a estrutura deles. Para os usuários do Windows, talvez seja preciso salvar os arquivos em UTF-8.
In [ ]: # converte arquivos ISO8859-15 para UTF-8 for filex in glob.glob('*.csv'):
i = 0
file=open(filex,'r',encoding='ISO-8859-1',errors="ignore") outp = open('utf8'+filex,"w")
s = filex.split("_") s = s[2].split('.') s = s[0]
print(s)
for f in file.readlines(): outp.write(f)
# para ver o início do arquivo e entender sua estrutura # if i < 15:
# print(f)
# i += 1 file.close() outp.close()
2
Lendo arquivos de dados para o Pandas
Os arquivos considerados possuem 12 linhas de comentários antes da linha de títulos das colunas.
In [ ]: file = 'utf8chuvas_C_02043052.csv' s = file.split('C') s = s[1].split('.') s = s[0].split('_') s = s[1] print('Estação = ', s) df = pd.read_csv(file,
sep=';', # separador dos dados ; header=0, # linhas de cabeçalho
skiprows=12, # pula 12 linhas
thousands=None, # não numero com separador de milhares: 1.000 (mil)
decimal=',') # indica explictamente que o separador de decimais é a vírgula print(df.head()) file = 'utf8chuvas_C_02043013.csv' s = file.split('C') s = s[1].split('.') s = s[0].split('_') s = s[1] print('\n','---', '\n') print('Estação = ', s) df1 = pd.read_csv(file,
sep=';', # separador dos dados ; header=0, # linhas de cabeçalho skiprows=12, # pula 12 linhas
thousands=None, # não numero com separador de milhares: 1.000 (mil)
decimal=',') # indica explictamente que o separador de decimais é a vírgula print(df1.head())
3
Título das colunas
Os campos ao serem copiados foram movidos para a direita em relação ao título, de forma que os dados da coluna(título) estão exibidos na coluna seguinte. Vamos renomear as colunas.
In [ ]: campos = ['EstacaoCodigo','NivelConsistencia','Data',
'TipoMedicaoChuvas','Maxima','Total','DiaMaxima', 'NumDiasDeChuva'] bd = df[campos]
novosNomes = ['NivelConsistencia','Data','TipoMedicaoChuvas', 'Maxima','Total','DiaMaxima','sobra1','sobra2'] bd.columns = novosNomes
bd=bd.drop(['sobra1','sobra2', 'TipoMedicaoChuvas',], axis=1) print(bd.head())
print('\n', '---','\n')
bd1 = df1[campos]
bd1.columns = novosNomes
bd1=bd1.drop(['sobra1','sobra2','TipoMedicaoChuvas'], axis=1) print(bd1.head())
4
Excluindo registros com dados ausentes
In [ ]: # excluir os nanbd.dropna(axis=0, how='any',inplace=True) print(bd.head())
print('\n', '---','\n') bd1.dropna(axis=0, how='any',inplace=True)
5
A quantidade de dados disponíveis
In [ ]: print(bd.shape[0])print(bd1.shape[0])
Nota 1: a estação de Congonhas possui 1595 dados, considerando por “intuição” que o regime de chuvas é o memso nas duas cidades, vamos usar apenas a estação de Congonhas. Essa discrepância entre as disponibilidades, demonstra um alto grau de comprometimento da CPRM/ANA (empresa pública) e um certo grau de apatia por parte da Açominas (empresa pri-vada) em obter os dados.
Nota 2: Os 1595 dados, que são mensais, correspondem a (1595/12) as 133 anos (?). Vamos verificar o que ocorreu. A coluna ‘NivelConsistencia’ mantem o dado bruto ‘=1’ e o dado con-sistido ‘=2’. O dado concon-sistido significa que o dado bruto foi avaliado por um especialista para estabelecer a qualidade dos dados.
In [ ]: #Dados consistidos # Dados brutos
DB = bd1[bd1['NivelConsistencia']==2] print(DB.head(5))
print('\n \n','Dados consistidos:', DB.shape[0],' equivale a ') print(DB.shape[0]/12,'anos. [Obs.: De 1941 a 2018 = 77 anos.]','\n')
# Dados brutos
DB1 = bd1[bd1['NivelConsistencia']==1] #print(bd1.head(),'\n', bd1.shape[0])
Nota 3:Houve uma mudança no nome das variáveis que contem a base de dados. De db1 para DB## Transformando tipo Object em tipo DateTime
Para transformar o campo Data no tipo DateTime. usar o campo Data como indexador. In [ ]: DB['Data'] = pd.to_datetime(DB['Data'], dayfirst=True)
# o index baseado na data DB = DB.set_index('Data')
#copia o indice para coluna DB['Data'] = DB.index
# converte para um datetimeindex do tipo dia/mês/ano DB['Data'] = DB['Data'].dt.strftime('%m/%d/%Y') print(DB.head())
6
Visualizando os dados
Os gráficos abaixo permite verificar que a distribuição da “nuvem de dados” é aleatória (dis-tribuição randômica). Os dados estão distribuidos em uma série temporal, de intervalo mensal. In [ ]: import matplotlib.dates as mdates
plt.plot(DB["Data"], DB["Total"],'r-',DB["Data"], DB["Maxima"], 'y-',DB["Data"], DB["DiaMaxima"],'b-');
plt.legend(['Total mensal','Máxima mensal','Máxima do dia' ])
7
Média e distribuição
Calculando a média e plotando histograma.
In [ ]: print('média = ', DB['Maxima'].mean()) # histograma
#plt.figure(figsize=(15, 8)) plt.hist(DB['Maxima'])
#plt.grid()
8
Usando o seaborn
O seaborn é uma biblioteca que permite fazer gráficos melhores e mais bonitos que a matplotlib. Note que o histograma recebe como envoltória a curva normal.
In [ ]: import seaborn as sns sns.distplot(DB.Total)
8.1 Desenhando Boxplot
In [ ]: dados = [DB['Maxima'], DB['Total'], DB['DiaMaxima']] plt.figure(figsize=(10,20))
plt.boxplot(dados, showfliers=True, vert=True); # vert=False plt.grid()
8.2 Agrupando os dados mensais em dados anuais In [ ]: DBanual = DB.resample('Y').max()
print(DBanual.head())
plt.figure(figsize=(20, 10)) plt.plot(DBanual["Total"]);