Analisando dados com Pandas

Helber Fernandes
5 min readNov 9, 2018

--

from site, original image by justgrimes: data (scrabble)(license)

Muitas vezes no nosso dia dia precisamos de analizar rapidamente nossos dados e gostariamos de obter algumas informações sobre eles, para ajudar na tomada de decisão, ou mesmo para o desenvolvimento de soluções. Neste momento temos de contar com algumas ferramentas para nos auxiliar neste trabalho, o pandas é uma ferramenta perfeita para este fim.

O DataSet

Para fins didáticos criei um dataset que representa um banco de dados de um hospital fictício, ele foi montado aleatoriamente, coletei algumas especialidades da lista especialidades médicas que pode ser encontrada aqui.

O dataset é composto da seguinte forma:

  • Id — um número sequencial
  • Data — data do atendimento
  • Horário — hora do atendimento
  • Especialidade — nome da Especialidade

Para iniciar temos de carregar nossos dados, neste caso vamos utilizar a função read_csv. Como nossos dados estão no idioma português devemos especificar o charset, para que não tenhamos problemas com os dados sendo exibidos de forma errada. Assim vamos usar o seguinte parâmetro para a função read_csv do pandas, encoding='iso-8859-1' .

Além disso vamos especificar nossa coluna de data para que o pandas possa realizar um parse nesta coluna transformando-a no tipo apropriado para nosso trabalho, isso é feito por meio do parâmetro parse_dates, em seguida vamos informar ao pandas que nossa data inicia com o dia ao invés do mês como é comum nos EUA, isto é feito da seguinte maneira dayfirst=True.

data = pd.read_csv('dataset.csv', delimiter=';', encoding='iso-8859-1', parse_dates=['data'], dayfirst=True)

Com nosso dataset carregado podemos então obter alguma informação sobre ele.

data.info()<class 'pandas.core.frame.DataFrame'>
RangeIndex: 22822 entries, 0 to 22821
Data columns (total 4 columns):
id 22822 non-null int64
data 22822 non-null datetime64[ns]
horario 22822 non-null object
especialidade 22822 non-null object
dtypes: datetime64[ns](1), int64(1), object(2)
memory usage: 713.3+ KB

Podemos perceber que o dataset possui 22822 registros, agora vamos exibir um pouco de nossos dados.

data.head()

Removendo dados desnecessários

Para este tutorial não precisaremos de todas as colunas do nosso dataset então, vamos remover algumas colunas, para isso basta agente usar o drop. Segundo o manual disponível aqui, dado uma lista de labels de colunas ou rows ele irá remover do dataset. Devemos especificar se desejamos remover uma linha ou coluna, para isso devemos informar o parametro axis que pode assumir os valores 0 para index e 1 para colunas, sendo que o padrão é o 0, sendo assim para removermos as colunas que não desejamos podemos fazer o seguinte:

data = data.drop(["horario"], axis=1)data.head()

Conhecendo as especialidades

Muito bem temos nosso dataset pronto para iniciarmos nosso estudo.

Vamos exibir quais especialidades temos no nosso dataset, para isso faremos o seguinte:

especialidades = data[['especialidade']].drop_duplicates().sort_values('especialidade').set_index('especialidade')
especialidades

O que acabamos de fazer foi o seguinte: por meio do fancy indexing (Indexação sofisticada em tradução livre :P) obtivemos todas as nossas especialidades, como temos várias especialidades repetidas chamamos a função drop_duplicates() para remover os registros duplicados e em seguida ordenamos o resultados, por fim neste caso apenas para uma melhor representação dos dados definimos a coluna especialidade como indice, experimente remover a função set_index('especialidade') para ver como fica o resultado.

Agora digamos que desejamos exibir apenas os 5 primeiros itens podemos então, fazer o seguinte:

especialidades[:5]

Da mesma forma podemos utilizar a função head e informar a quantidade desejada de itens. Ou seja esta função retorna as n primeiras linhas do nosso dataset.

especialidades.head(5)

Extraindo informações

Agora que sabemos quais especialidades temos, vamos contar quantos registros temos em cada especialidade, para isso precisamos agrupar nossos dados pela especialidade e em seguida informar quais campos queremos contar.

data.groupby(['especialidade']).especialidade.count()especialidade
Cardiologista 2
Clínica Médica 14416
Dermatologista 6
Ecocardiografia 2
Ecografia 1
Ginecologista 2
Mamografia 1
Neurologia 575
Oftalmologista 1
Ortopedia 3442
Ortopedista 1
Pediatria 2210
Psiquiatria 1338
Radiologia 821
Urologia 4
Name: especialidade, dtype: int64

Uma outra maneira e mais simples de conseguirmos o mesmo resultado seria apenas apontarmos a coluna que desejamos em seguida chamarmos a função value_counts(), como podemos ver a seguir.

data.especialidade.value_counts()Clínica Médica     14416
Ortopedia 3442
Pediatria 2210
Psiquiatria 1338
Radiologia 821
Neurologia 575
Dermatologista 6
Urologia 4
Cardiologista 2
Ginecologista 2
Ecocardiografia 2
Ortopedista 1
Ecografia 1
Oftalmologista 1
Mamografia 1
Name: especialidade, dtype: int64

Se observarmos ao executar o código anterior recebemos um objeto do tipo Series.

type(data.especialidade.value_counts())pandas.core.series.Series

Como então obtermos o mesmo resultado mas desta vez recebendo um objeto do tipo DataFrame? para isso basta adicionarmos a função reset_index() ela nos retornará um objeto DataFrame, aproveito para renomear as colunas.

data.especialidade.value_counts().reset_index().rename(columns={'index': 'Especialidade', 'especialidade': 'Total'})

Muito bem, agora digamos que você deseja saber quantos atendimentos a empresa teve por ano?.

data.groupby(data['data'].dt.year).size()data
2017 13073
2018 9749
dtype: int64

Inicialmente obtemos a coluna data e em seguida pegamos o objeto do tipo DatetimeProperties para que possamos obter por sua vez o atributo year que nos da o ano da nossa data, para somente depois agruparmos os dados por ano e por fim obtermos o total de atendimentos por ano.

Podemos obter os dados da mesma maneira, mas agora retornarmos o objeto como um DataFrame.

data.groupby(data['data'].dt.year).size().reset_index().rename(columns={0: 'Total'}).set_index('data')

Agora sabemos que no ano de 2017 tivemos 13073 atendimentos enquanto o ano de 2018 tivemos apenas 9749 totalizando 22822 registros.

Muito bem, agora e se nós desejamos saber quanto cada especialidade atendeu por ano? para isso basta agrupar os dados por ano e especialidade.

data.groupby([data['data'].dt.year, 'especialidade'])[['id']].count().rename(columns={'id': 'Total'})

Assim descobrimos que nem todas as especialidades atuaram em 2018 por exemplo. Agora e se ao contrário gostariamos de saber o total de atendimento por mes e ano?.

data.groupby([data['data'].dt.year, data['data'].dt.month])[['id']].count().rename(columns={'id': 'Total'})

Para finalizar vamos agrupar todos, ano, mes e especialidade.

Normalmente o pandas mostra várias linhas, porém para ficar uma imagem melhor de ser exibida limitei os registro da seguinte manera:

pd.set_option(“display.max_rows”,10)data.groupby([data['data'].dt.year, data['data'].dt.month, 'especialidade'])[['id']].count().rename(columns={'id': 'Total'})

Você pode encontrar o Jupyter notebook no Github.

Veja também: Analisando Dados com Pandas as Duas Torres.

--

--