Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

[Sugestão] 02_Exploração_dos_dados_Faça_como_eu_fiz

## 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}")
1 resposta
solução!

Marinaldo, parabéns, ficou muito bom!

Ficou excelente mesmo.

Uma sugestão importante: Tente manter um padrão de estilo no seu código, evitando ter algumas strings com aspas simples e outras com aspas duplas. Isso é uma boa prática, e é mais importante do que parece.

Já aqui não é uma sugestão, pois o código está muito bem escrito, mas é mostrar uma outra forma de fazer a mesma coisa, assim você conhece ambas e pode escolher qual se adequa mais ao seu caso:

O seguinte código:

    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}")

Também pode ser escrito da seguinte maneira:

match laranja, toranja:
    case None, None:
        pass
    case _, None:  # ou case laranja, None
        print(f"{i:5} | {laranja_str} ||")
    case None, _:  # ou case None, toranja
        print(f"      | {'':21} || {linha_toranja:5} | {toranja_str}")
    case _, _:  # ou case _ ou case laranja, toranja
        print(f"{i:5} | {laranja_str} || {linha_toranja:5} | {toranja_str}")

Bom, é apenas outra maneira, não necessariamente uma sugestão, pois a sua execução está muito boa. Mais uma vez, parabéns!