Olá, Ana. Como vai?
Parabéns pela resolução do desafio! O seu código está excelente, muito bem estruturado e você foi além ao aplicar os conceitos extras de tratamento de dados, cálculo de média e filtros. É muito bom ver você explorando essas ferramentas do Pandas.
Gostaria apenas de levantar dois pontos bem importantes sobre o comportamento do Jupyter Notebook / Colab e sobre as boas práticas no seu código para te ajudar a fixar ainda mais o conhecimento:
1. Visualização de múltiplos DataFrames na mesma célula (Item 2)
No seu item 2, você colocou duas linhas de comando seguidas:
df.head(7)
df.tail()
Em ambientes como o Google Colab ou Jupyter Notebook, quando colocamos dois comandos que geram saídas visuais diretamente na mesma célula, apenas o último comando é exibido na tela. Ou seja, do jeito que está, você só conseguirá ver as 5 últimas linhas (df.tail()), e o df.head(7) será "escondido".
Para conseguir visualizar os dois resultados ao mesmo tempo, a boa prática é utilizar a função display() para cada um deles, ou separá-los em células diferentes. Exemplo com display():
display(df.head(7))
display(df.tail())
2. Otimização do Filtro e Criação de Colunas (Extra)
A sua lógica para criar a coluna Aprovado usando o df.loc funcionou perfeitamente. Porém, quando usamos essa estrutura, as linhas onde a nota foi menor que a média ficam preenchidas com o valor NaN (vazio) na nova coluna, em vez de False.
Uma forma mais elegante, rápida e considerada uma grande boa prática no Pandas para criar colunas booleanas (Verdadeiro/Falso) é fazer uma atribuição direta baseada em uma condição. O Pandas já faz essa checagem linha por linha automaticamente:
# Cria a coluna com True para quem passou e False para quem ficou abaixo da média
df['Aprovado'] = df['Notas'] >= media
O método describe() solicitado no Extra
Como você mencionou a dica do método describe() no enunciado, vale a pena incluí-lo no seu script para obter o resumo estatístico completo de uma vez só (média, desvio padrão, valores mínimos, máximos e quartetos). Você pode chamá-lo assim:
# Mostra estatísticas de todas as colunas numéricas
df.describe()
O seu código final com essas pequenas melhorias ficaria super limpo e profissional:
import pandas as pd
# 1 - Importando os dados
url = 'https://raw.githubusercontent.com/alura-cursos/pandas-conhecendo-a-biblioteca/main/desafios/alunos.csv'
df = pd.read_csv(url)
# 2 - Visualizando linhas (usando display para mostrar ambos)
display(df.head(7))
display(df.tail())
# 3 e 4 - Dimensões e Tipos de dados
print(f"Dimensões do DataFrame: {df.shape}")
print("\nTipos de dados por coluna:")
print(df.dtypes)
# Extras - Tratamento, Estatística e Filtros
df['Notas'] = df['Notas'].fillna(0)
print("\nResumo Estatístico das Notas:")
display(df['Notas'].describe())
media = df['Notas'].mean()
print(f"\nA média geral é: {media:.2f}")
# Criação da coluna booleana de forma direta
df['Aprovado'] = df['Notas'] >= media
# Filtrando e ordenando os aprovados
alunos_aprovados = df[df['Aprovado'] == True][['Nome', 'Notas']].sort_values(by='Notas', ascending=False)
display(alunos_aprovados)
Você mandou muito bem na iniciativa de tratar os valores nulos com o .fillna(0) antes de calcular a média. Continue com essa curiosidade e foco nos estudos!
Espero que possa ter lhe ajudado!