import pandas as pd
import matplotlib.pyplot as plt
from urllib.request import urlopen
from urllib.parse import urlparse
import io
import csv
import logging
# Configuração de logging
logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')
def detectar_separador(conteudo_bytes):
"""Detecta o separador do CSV usando csv.Sniffer"""
try:
amostra = conteudo_bytes[:1024].decode('utf-8')
dialeto = csv.Sniffer().sniff(amostra)
return dialeto.delimiter
except Exception as e:
logging.warning(f'Não foi possível detectar o separador: {e}')
return ',' # fallback seguro
def extrair_extensao(url):
"""Extrai a extensão do arquivo da URL"""
caminho = urlparse(url).path
return caminho.split('.')[-1].lower()
def carregar_dados(url):
"""Baixa e carrega dados em um DataFrame do pandas, com suporte a múltiplos formatos"""
extensao = extrair_extensao(url)
try:
conteudo = urlopen(url).read()
except Exception as e:
raise RuntimeError(f'Erro ao acessar a URL: {e}')
buffer = io.BytesIO(conteudo)
match extensao:
case 'csv':
sep = detectar_separador(conteudo)
return pd.read_csv(buffer, encoding='utf-8', sep=sep)
case 'xls' | 'xlsx':
return pd.read_excel(buffer)
case 'json':
return pd.read_json(buffer)
case _:
raise ValueError(f'Extensão de arquivo não suportada: .{extensao}')
# URL
url = 'https://raw.githubusercontent.com/alura-cursos/pandas-conhecendo-a-biblioteca/main/base-de-dados/aluguel.csv'
# Carregar dados
dados = carregar_dados(url).copy()
logging.info('Dados carregados com sucesso.')
# Filtrar apartamentos
apartamentos = dados[dados['Tipo'] == 'Apartamento']
quantidade_apartamentos = apartamentos.shape[0]
media_quartos = apartamentos['Quartos'].mean()
print(f'Quantidade de apartamentos: {quantidade_apartamentos}')
print(f'Média de quartos nos apartamentos: {media_quartos:.2f}')
# Bairros únicos
bairros_unicos = dados['Bairro'].nunique()
print(f'Quantidade de bairros únicos: {bairros_unicos}')
print(f'Bairros únicos: {dados["Bairro"].unique()}')
# Agrupamento por bairro
dados_filtrados = dados.dropna(subset=['Valor', 'Bairro']) # evitar NaNs problemáticos
quantidade_por_bairro = dados_filtrados['Bairro'].value_counts()
media_aluguel_bairro = dados_filtrados.groupby('Bairro')['Valor'].mean()
df_bairros = pd.DataFrame({
'media_aluguel': media_aluguel_bairro,
'quantidade': quantidade_por_bairro
}).dropna()
df_bairros['porcentagem'] = df_bairros['quantidade'] / df_bairros['quantidade'].sum() * 100
# Top 5 bairros por aluguel
top5 = df_bairros.sort_values('media_aluguel', ascending=False).head(5)
# Gráfico de barras horizontais
ax = top5['media_aluguel'].plot(kind='barh', title='Média de Aluguel por Bairro (Top 5)')
plt.xlabel('Média de Aluguel')
plt.ylabel('Bairro')
# Adiciona as porcentagens ao final de cada barra
for i, (bairro, row) in enumerate(top5.iterrows()):
ax.text(row['media_aluguel'] + 20, i, f"{row['porcentagem']:.1f}%", va='center', fontsize=10)
plt.tight_layout()
plt.show()