## Chegou a hora de você testar os conhecimentos desenvolvidos durante a aula. Continuando com o projeto das laranjas/toranjas agora você deve selecionar parte dos dados. As colunas que iremos avaliar são as de diâmetro e peso. Crie arrays específicos para guardar o diâmetro e peso da laranja e toranja. O diâmetro está na coluna zero e o peso na coluna 1. Os dados referentes a laranja vão até a linha 4999 e os referentes à toranja iniciam na linha 5000 do arquivo. Após fazer a seleção de dados, importe a biblioteca matplotlib e crie um gráfico para a laranja e para a toranja do peso pelo diâmetro.
# -*- coding: utf-8 -*-
from urllib.request import urlopen
import numpy as np
from itertools import zip_longest
import matplotlib.pyplot as plt
# === Funções utilitárias ===
def proximo_valido(coluna, indice, sentido='antes'):
"""Retorna o valor válido mais próximo antes ou depois de um índice em uma coluna."""
if sentido == 'antes':
for i in range(indice - 1, -1, -1):
if not np.isnan(coluna[i]):
return coluna[i]
elif sentido == 'depois':
for i in range(indice + 1, len(coluna)):
if not np.isnan(coluna[i]):
return coluna[i]
return None
def preencher_nan_com_media_vizinhos(array):
"""Substitui NaNs em um array 2D pela média dos valores válidos antes e depois usando np.mean()."""
for i in range(array.shape[0]):
for j in range(array.shape[1]):
if np.isnan(array[i, j]):
valores_validos = []
antes = proximo_valido(array[:, j], i, sentido='antes')
depois = proximo_valido(array[:, j], i, sentido='depois')
if antes is not None:
valores_validos.append(antes)
if depois is not None:
valores_validos.append(depois)
if valores_validos:
array[i, j] = np.mean(valores_validos)
return array
# === Carregamento dos dados ===
url = 'https://raw.githubusercontent.com/allanspadini/numpy/dados/citrus.csv'
url_array = urlopen(url)
dados = np.loadtxt(url_array, delimiter=',', skiprows=1, usecols=np.arange(1, 3))
# Verifica e corrige NaNs
qtd_nans_antes = np.isnan(dados).sum()
dados = preencher_nan_com_media_vizinhos(dados)
qtd_nans_depois = np.isnan(dados).sum()
print(f"Foram corrigidos {qtd_nans_antes - qtd_nans_depois} valores NaN.\n")
# Separa os dados
laranjas_array = dados[:5000]
toranjas_array = dados[5000:]
# Ordena pelo diâmetro (coluna 0) para linhas contínuas coerentes
laranjas_array = laranjas_array[laranjas_array[:, 0].argsort()]
toranjas_array = toranjas_array[toranjas_array[:, 0].argsort()]
# Ajusta toranja para começar no ponto inicial da laranja
ponto_inicial_laranja = laranjas_array[0]
if not np.isclose(toranjas_array[0, 0], ponto_inicial_laranja[0]):
toranjas_array = np.vstack([ponto_inicial_laranja, toranjas_array])
# === GRÁFICO DE LINHA CONTÍNUA ===
plt.figure(figsize=(10, 6))
plt.plot(laranjas_array[:, 0], laranjas_array[:, 1], label='Laranjas', linewidth=1)
plt.plot(toranjas_array[:, 0], toranjas_array[:, 1], label='Toranjas', linewidth=1)
plt.xlabel('Diâmetro')
plt.ylabel('Peso')
plt.title('Distribuição de Laranjas e Toranjas por Diâmetro e Peso (Linha Contínua)')
plt.legend()
plt.grid(True, linestyle='--', linewidth=0.3)
plt.tight_layout()
plt.show()
# === IMPRESSÃO TABULAR ===
print(f"{'LARANJAS':^30} || {'TORANJAS':^30}")
print(f"{'Linha':>5} | {'Diâmetro':>9} | {'Peso':>9} || {'Linha':>5} | {'Diâmetro':>9} | {'Peso':>9}")
print('-' * 65)
for i, (laranja, toranja) in enumerate(zip_longest(laranjas_array, toranjas_array), start=0):
if laranja is not None:
diam_l, peso_l = laranja
laranja_str = f"{diam_l:9.2f} | {peso_l:9.2f}"
else:
laranja_str = " " * 21
linha_toranja = i + len(laranjas_array)
if toranja is not None:
diam_t, peso_t = toranja
toranja_str = f"{diam_t:9.2f} | {peso_t:9.2f}"
else:
toranja_str = ""
if laranja is not None and toranja is not None:
print(f"{i:5} | {laranja_str} || {linha_toranja:5} | {toranja_str}")
elif laranja is not None:
print(f"{i:5} | {laranja_str} ||")
elif toranja is not None:
print(f" | {'':21} || {linha_toranja:5} | {toranja_str}")