Estatísticas Descritivas

No módulo anterior, limpamos e enriquecemos nosso dataset dos pinguins, criando variáveis derivadas e garantindo qualidade dos dados. Agora chegou o momento de quantificar padrões e revelar insights através de estatísticas descritivas.

Cada número que calcularemos tem significado biológico real: a massa corporal média nos conta sobre o tamanho das espécies, a variação nas dimensões do bico revela especialização alimentar, e as correlações conectam morfologia à ecologia.

Este módulo transforma nossos dados limpos em histórias quantitativas sobre os pinguins antarcticos, preparando o terreno para as visualizações impactantes dos próximos módulos.

Preparando o Ambiente com Nossos Pinguins Limpos

Carregando Nossos Pinguins Limpos

penguins_raw = pd.read_csv('https://raw.githubusercontent.com/allisonhorst/palmerpenguins/master/inst/extdata/penguins.csv')
penguins = penguins_raw.dropna()
glimpse(penguins)
Rows: 333
Columns: 8
> species           object  0 (0%) NAs : Adelie, Adelie, Adelie, Adelie, Adelie
> island            object  0 (0%) NAs : Torgersen, Torgersen, Torgersen, Torgersen, Torgersen
> bill_length_mm    float64 0 (0%) NAs : 39.1, 39.5, 40.3, 36.7, 39.3
> bill_depth_mm     float64 0 (0%) NAs : 18.7, 17.4, 18.0, 19.3, 20.6
> flipper_length_mm float64 0 (0%) NAs : 181.0, 186.0, 195.0, 193.0, 190.0
> body_mass_g       float64 0 (0%) NAs : 3750.0, 3800.0, 3250.0, 3450.0, 3650.0
> sex               object  0 (0%) NAs : male, female, female, female, male
> year              int64   0 (0%) NAs : 2007, 2007, 2007, 2007, 2007

Fundamentos das Estatísticas Descritivas nos Pinguins

O que Revelaremos sobre os Pinguins?

As estatísticas descritivas nos permitem quantificar padrões biológicos nos nossos pinguins:

  • Centralidade: Qual é o tamanho típico de cada espécie?
  • Variabilidade: Quão diversos são os indivíduos dentro de cada grupo?
  • Forma da distribuição: Há assimetrias nas medidas morfológicas?
  • Valores atípicos: Existem pinguins excepcionalmente grandes ou pequenos?
  • Dimorfismo: Machos e fêmeas diferem sistematicamente?
Nota🧬 Nossa Abordagem: Cientifico-Descritiva
  • Descritivas: Quantificamos os 333 pinguins observados na Antártica
  • Contexto biológico: Cada estatística terá interpretação ecológica real
  • Grupos naturais: Analisaremos por espécie, sexo e ilha de origem
  • Variáveis derivadas: Exploraremos nossos índices criados (BMI, especialização do bico)

Cada número contará uma história sobre a biologia dos pinguins!

Mapeando Nossas Variáveis dos Pinguins

# Variáveis quantitativas originais

quantitative_vars = ['bill_length_mm', 'bill_depth_mm', 'flipper_length_mm', 'body_mass_g']

for var in quantitative_vars:
    min_val, max_val = penguins[var].min(), penguins[var].max()
    print(f"{var}: {min_val:.1f} a {max_val:.1f}")

print("\n🏷️ VARIÁVEIS CATEGÓRICAS:")
categorical_vars = {
    'species': 'Nominal (Adelie, Chinstrap, Gentoo)',
    'island': 'Nominal (Biscoe, Dream, Torgersen)', 
    'sex': 'Nominal (female, male)'
}

for var, description in categorical_vars.items():
    unique_vals = penguins[var].nunique()
    print(f"  {var}: {description} ({unique_vals} categorias)")

print("\n🗓️ VARIÁVEL DISCRETA:")
print(f"  year: {penguins['year'].unique()} (anos de coleta)")
bill_length_mm: 32.1 a 59.6
bill_depth_mm: 13.1 a 21.5
flipper_length_mm: 172.0 a 231.0
body_mass_g: 2700.0 a 6300.0

🏷️ VARIÁVEIS CATEGÓRICAS:
  species: Nominal (Adelie, Chinstrap, Gentoo) (3 categorias)
  island: Nominal (Biscoe, Dream, Torgersen) (3 categorias)
  sex: Nominal (female, male) (2 categorias)

🗓️ VARIÁVEL DISCRETA:
  year: [2007 2008 2009] (anos de coleta)

Estratégia de Análise:

  • Quantitativas: Medidas centrais, dispersão, forma, correlações
  • Categóricas: Frequências, proporções, comparações entre grupos
  • Combinações: Estatísticas por grupos (espécie, sexo, ilha)

Medidas de Tendência Central: Descobrindo o “Pinguim Típico”

Média: O Pinguim “Médio” de Cada Espécie

A média nos dá o valor típico considerando todos os indivíduos. Vamos calcular a massa corporal média geral e por espécie para identificar diferenças entre grupos.

# Calcular média geral e por espécie
media_geral = penguins['body_mass_g'].mean()
media_por_especie = penguins.groupby('species')['body_mass_g'].agg(['mean', 'count'])

# Adicionar média geral como linha
media_por_especie.loc['Geral'] = [media_geral, len(penguins)]
media_por_especie.columns = ['Média (g)', 'N']

# Arredondar valores
media_por_especie = media_por_especie.round(0)
media_por_especie
Média (g) N
species
Adelie 3706.0 146.0
Chinstrap 3733.0 68.0
Gentoo 5092.0 119.0
Geral 4207.0 333.0

Gentoo são os pinguins mais pesados (5092g), quase 40% maiores que Adelie e Chinstrap (ambos ~3700g). Esta diferença de 1400g entre espécies sugere nichos ecológicos distintos, com Gentoo ocupando um papel diferente no ecossistema antártico.

Dimorfismo Sexual por Espécie

O dimorfismo sexual é a diferença de tamanho entre machos e fêmeas. Vamos analisar se existe dimorfismo na massa corporal e como ele varia entre espécies.

# Calcular médias por espécie e sexo
sex_stats = penguins.groupby(['species', 'sex'])['body_mass_g'].agg(['mean', 'count']).round(0)
sex_stats.columns = ['Média (g)', 'N']

# Calcular razão macho/fêmea para cada espécie
dimorphism_ratios = []
for species in penguins['species'].unique():
    species_data = penguins[penguins['species'] == species]
    sex_means = species_data.groupby('sex')['body_mass_g'].mean()
    if len(sex_means) == 2:
        ratio = sex_means['male'] / sex_means['female']
        dimorphism_ratios.append({'Espécie': species, 'Razão M/F': f"{ratio:.2f}x"})

sex_stats
Média (g) N
species sex
Adelie female 3369.0 73
male 4043.0 73
Chinstrap female 3527.0 34
male 3939.0 34
Gentoo female 4680.0 58
male 5485.0 61
# Tabela de dimorfismo
dimorphism_df = pd.DataFrame(dimorphism_ratios)
dimorphism_df
Espécie Razão M/F
0 Adelie 1.20x
1 Gentoo 1.17x
2 Chinstrap 1.12x

Todas as espécies mostram dimorfismo sexual moderado, com machos 12-20% maiores. Adelie apresentam maior diferença (20%), possivelmente relacionado à sua distribuição em múltiplas ilhas, enquanto Chinstrap mostram menor dimorfismo (12%). Esse padrão sugere diferentes pressões evolutivas entre as espécies.

Especialização Morfológica do Bico

A razão comprimento/profundidade do bico indica especialização alimentar. Vamos criar essa variável derivada para analisar padrões evolutivos.

# Criar a razão do bico para análise de especialização alimentar
penguins['bill_ratio'] = penguins['bill_length_mm'] / penguins['bill_depth_mm']

# Calcular estatísticas da especialização do bico
bill_stats = penguins.groupby('species')['bill_ratio'].agg(['mean', 'std', 'min', 'max']).round(2)
bill_stats.columns = ['Média', 'Desvio', 'Mínimo', 'Máximo']

# Adicionar interpretação biológica
interpretations = []
for species in bill_stats.index:
    ratio = bill_stats.loc[species, 'Média']
    if ratio > 2.5:
        interp = "Bico alongado (peixes/lulas)"
    elif ratio < 2.0:
        interp = "Bico robusto (krill/crustáceos)"
    else:
        interp = "Bico intermediário"
    interpretations.append(interp)

bill_stats['Especialização'] = interpretations
bill_stats
Média Desvio Mínimo Máximo Especialização
species
Adelie 2.12 0.16 1.64 2.45 Bico intermediário
Chinstrap 2.65 0.15 2.35 3.26 Bico alongado (peixes/lulas)
Gentoo 3.18 0.17 2.57 3.61 Bico alongado (peixes/lulas)

Gentoo apresentam bicos mais alongados (razão 3.18), seguidos por Chinstrap (2.65) e Adelie (2.12). Esta progressão sugere especializações alimentares distintas: bicos alongados podem indicar adaptação para presas maiores como peixes, enquanto bicos mais robustos podem ser eficientes para presas menores como krill.

Mediana: Valor Central e Robustez a Outliers

A mediana é o valor que divide os dados ao meio e é mais resistente a valores extremos que a média. Vamos comparar ambas medidas para avaliar a simetria das distribuições.

# Comparar média vs mediana por espécie
central_stats = penguins.groupby('species')['body_mass_g'].agg(['mean', 'median']).round(0)
central_stats['Diferença'] = abs(central_stats['mean'] - central_stats['median'])
central_stats.columns = ['Média (g)', 'Mediana (g)', 'Diferença (g)']

central_stats
Média (g) Mediana (g) Diferença (g)
species
Adelie 3706.0 3700.0 6.0
Chinstrap 3733.0 3700.0 33.0
Gentoo 5092.0 5050.0 42.0

As pequenas diferenças entre média e mediana (6-42g) indicam distribuições aproximadamente simétricas. Gentoo mostram maior diferença (42g), sugerindo uma leve assimetria na distribuição de massa, possivelmente com alguns indivíduos excepcionalmente grandes.

Teste de Robustez: Média vs Mediana

Vamos demonstrar como a mediana é mais resistente a valores extremos simulando um pinguim “gigante” de 1000kg (1 tonelada).

# Comparar robustez com outlier extremo (1000kg)
original_data = penguins['body_mass_g']
with_outlier = pd.concat([original_data, pd.Series([1000000])])  # 1000kg outlier

# Criar tabela comparativa
robustez_teste = pd.DataFrame({
    'Condição': ['Dados Originais', 'Com Outlier (1000kg)'],
    'Média (g)': [
        f"{original_data.mean():.0f}",
        f"{with_outlier.mean():.0f} (+{with_outlier.mean() - original_data.mean():.0f})"
    ],
    'Mediana (g)': [
        f"{original_data.median():.0f}",
        f"{with_outlier.median():.0f} (+{with_outlier.median() - original_data.median():.0f})"
    ],
    'Impacto': [
        'Base',
        f'Média: +{(with_outlier.mean()/original_data.mean()-1)*100:.1f}% / Mediana: +{(with_outlier.median()/original_data.median()-1)*100:.1f}%'
    ]
})

robustez_teste
Condição Média (g) Mediana (g) Impacto
0 Dados Originais 4207 4050 Base
1 Com Outlier (1000kg) 7188 (+2981) 4050 (+0) Média: +70.9% / Mediana: +0.0%

O outlier extremo demonstra claramente por que a mediana é mais robusta: enquanto a média dispara 71% (+2981g), a mediana permanece inalterada. Isso mostra que a mediana representa melhor o “pinguim típico” quando há valores extremos nos dados.

Quando Usar Mediana vs. Média?

A escolha entre média e mediana depende da forma da distribuição dos dados.

# Calcular assimetria das principais variáveis
assimetria_dados = []
for var in ['body_mass_g', 'bill_length_mm', 'flipper_length_mm']:
    skew_val = stats.skew(penguins[var])
    assimetria_dados.append({'Variável': var, 'Assimetria': skew_val})

assimetria_df = pd.DataFrame(assimetria_dados)
assimetria_df['Variável'] = ['Massa Corporal', 'Comprimento Bico', 'Comprimento Nadadeira']
assimetria_df['Assimetria'] = assimetria_df['Assimetria'].round(3)
assimetria_df
Variável Assimetria
0 Massa Corporal 0.470
1 Comprimento Bico 0.045
2 Comprimento Nadadeira 0.359

Interpretação: Todas as variáveis apresentam assimetria baixa (< 0.5), indicando distribuições aproximadamente simétricas. Isso significa que média e mediana são equivalentes para nossos dados de pinguins, e podemos usar qualquer uma com confiança.

Para dados com assimetria alta (> 0.5), a mediana seria mais representativa que a média.

Moda: Valores Mais Frequentes

A moda identifica os valores mais comuns. Para variáveis categóricas, é o valor com maior frequência.

# Frequências das variáveis categóricas principais
species_freq = penguins['species'].value_counts()
island_freq = penguins['island'].value_counts()
sex_freq = penguins['sex'].value_counts()

# Criar DataFrame resumo
frequency_summary = pd.DataFrame({
    'Espécie': [f"{species_freq.index[0]} ({species_freq.iloc[0]} pinguins)"],
    'Ilha': [f"{island_freq.index[0]} ({island_freq.iloc[0]} pinguins)"],
    'Sexo': [f"{sex_freq.index[0]} ({sex_freq.iloc[0]} pinguins)"]
}, index=['Mais Frequente'])

frequency_summary
Espécie Ilha Sexo
Mais Frequente Adelie (146 pinguins) Biscoe (163 pinguins) male (168 pinguins)
# Distribuição completa por espécie
species_table = pd.DataFrame({
    'Frequência': species_freq,
    'Percentual': (species_freq / len(penguins) * 100).round(1)
})
species_table['Percentual'] = species_table['Percentual'].astype(str) + '%'

species_table
Frequência Percentual
species
Adelie 146 43.8%
Gentoo 119 35.7%
Chinstrap 68 20.4%

Moda para Variáveis Quantitativas

Para variáveis numéricas, agrupamos os dados em faixas para identificar os valores mais frequentes.

# Faixa de massa corporal mais comum (dividida em 10 grupos)
mass_bins = pd.cut(penguins['body_mass_g'], bins=10)
mass_frequency = mass_bins.value_counts().head(3)

mass_modal_analysis = pd.DataFrame({
    'Faixa de Massa (g)': mass_frequency.index.astype(str),
    'Frequência': mass_frequency.values,
    'Percentual (%)': (mass_frequency.values / len(penguins) * 100).round(1)
})

mass_modal_analysis
Faixa de Massa (g) Frequência Percentual (%)
0 (3420.0, 3780.0] 69 20.7
1 (3780.0, 4140.0] 52 15.6
2 (4140.0, 4500.0] 44 13.2
# Distribuição por ano de coleta
year_distribution = penguins['year'].value_counts().sort_index()

year_table = pd.DataFrame({
    'Ano': year_distribution.index,
    'Pinguins Observados': year_distribution.values,
    'Percentual (%)': (year_distribution.values / len(penguins) * 100).round(1)
})

year_table
Ano Pinguins Observados Percentual (%)
0 2007 103 30.9
1 2008 113 33.9
2 2009 117 35.1

Medidas de Dispersão: Quão Diversos São os Pinguins?

Amplitude: Diferenças Entre Extremos

A amplitude revela a variação total observada entre os pinguins mais extremos de cada medida.

# Calcular amplitude para características principais
variables_of_interest = {
    'body_mass_g': 'Massa corporal (g)',
    'bill_length_mm': 'Comprimento do bico (mm)', 
    'bill_depth_mm': 'Profundidade do bico (mm)',
    'flipper_length_mm': 'Comprimento da nadadeira (mm)'
}

amplitude_data = []
for var, description in variables_of_interest.items():
    min_val = penguins[var].min()
    max_val = penguins[var].max()
    amplitude = max_val - min_val
    variacao_perc = (amplitude/min_val*100)
    
    amplitude_data.append({
        'Característica': description,
        'Mínimo': f"{min_val:.0f}",
        'Máximo': f"{max_val:.0f}",
        'Amplitude': f"{amplitude:.0f}",
        'Variação (%)': f"{variacao_perc:.0f}%"
    })

amplitude_df = pd.DataFrame(amplitude_data)
amplitude_df
Característica Mínimo Máximo Amplitude Variação (%)
0 Massa corporal (g) 2700 6300 3600 133%
1 Comprimento do bico (mm) 32 60 28 86%
2 Profundidade do bico (mm) 13 22 8 64%
3 Comprimento da nadadeira (mm) 172 231 59 34%

Massa corporal mostra a maior variabilidade (133% de variação), refletindo as grandes diferenças entre espécies. Comprimento do bico também varia substancialmente (86%), confirmando especializações alimentares distintas. Comprimento da nadadeira é a medida mais estável (34%), sugerindo requisitos hidrodinâmicos similares para todas as espécies.

Amplitude Interquartil (IQR)

O IQR foca nos 50% centrais dos dados, sendo mais robusto a valores extremos que a amplitude total.

# Calcular IQR para cada variável
iqr_data = []
for var, description in variables_of_interest.items():
    Q1 = penguins[var].quantile(0.25)
    Q3 = penguins[var].quantile(0.75)
    IQR = Q3 - Q1
    median_val = penguins[var].median()
    amplitude_total = penguins[var].max() - penguins[var].min()
    iqr_vs_total = IQR/amplitude_total*100
    
    iqr_data.append({
        'Característica': description,
        'Q1': f"{Q1:.0f}",
        'Mediana': f"{median_val:.0f}",
        'Q3': f"{Q3:.0f}",
        'IQR': f"{IQR:.0f}",
        'IQR/Total (%)': f"{iqr_vs_total:.0f}%"
    })

iqr_df = pd.DataFrame(iqr_data)
iqr_df
Característica Q1 Mediana Q3 IQR IQR/Total (%)
0 Massa corporal (g) 3550 4050 4775 1225 34%
1 Comprimento do bico (mm) 40 44 49 9 33%
2 Profundidade do bico (mm) 16 17 19 3 37%
3 Comprimento da nadadeira (mm) 190 197 213 23 39%

2. Variância e Desvio Padrão: Medindo Diversidade Intra-Espécie

O desvio padrão nos diz quão “dispersos” são os pinguins de cada espécie.

Variabilidade da Massa Corporal por Espécie

O desvio padrão quantifica a dispersão dos indivíduos em relação à média da espécie.

# Calcular estatísticas de variabilidade por espécie
variability_data = []
for species in penguins['species'].unique():
    species_data = penguins[penguins['species'] == species]['body_mass_g']
    mean_val = species_data.mean()
    std_val = species_data.std()
    cv = (std_val / mean_val) * 100
    
    variability_data.append({
        'Espécie': species,
        'Média (g)': f"{mean_val:.0f}",
        'Desvio Padrão (g)': f"{std_val:.0f}",
        'CV (%)': f"{cv:.1f}%"
    })

variability_df = pd.DataFrame(variability_data)
variability_df
Espécie Média (g) Desvio Padrão (g) CV (%)
0 Adelie 3706 459 12.4%
1 Gentoo 5092 501 9.8%
2 Chinstrap 3733 384 10.3%

Adelie são mais variáveis internamente (CV = 12.4%), possivelmente devido à distribuição em três ilhas com condições diferentes. Gentoo, apesar de maiores, são mais homogêneos (CV = 9.8%), sugerindo condições ambientais mais estáveis na ilha Biscoe.

Teste da Regra Empírica (68-95-99.7)

Verificamos se os dados seguem a regra empírica usando os pinguins Adelie como exemplo.

# Testar regra dos 68% com Adelie
adelie_data = penguins[penguins['species'] == 'Adelie']['body_mass_g']
adelie_mean = adelie_data.mean()
adelie_std = adelie_data.std()

lower_bound = adelie_mean - adelie_std
upper_bound = adelie_mean + adelie_std
within_1std = adelie_data[(adelie_data >= lower_bound) & (adelie_data <= upper_bound)]
actual_percentage = len(within_1std) / len(adelie_data) * 100

regra_empirica = pd.DataFrame({
    'Métrica': ['Faixa (1σ)', 'Percentual Observado', 'Percentual Teórico', 'Diferença'],
    'Valor': [f"{lower_bound:.0f}g - {upper_bound:.0f}g", f"{actual_percentage:.1f}%", "68.0%", f"{actual_percentage-68:.1f}%"]
})

regra_empirica
Métrica Valor
0 Faixa (1σ) 3248g - 4165g
1 Percentual Observado 65.8%
2 Percentual Teórico 68.0%
3 Diferença -2.2%

Uniformidade Entre Espécies

Comparamos a variabilidade interna de cada espécie usando coeficiente de variação para diferentes características.

# Calcular CV por espécie para múltiplas características
uniformity_data = []
for species in penguins['species'].unique():
    species_data = penguins[penguins['species'] == species]
    
    cv_mass = (species_data['body_mass_g'].std() / species_data['body_mass_g'].mean()) * 100
    cv_bill = (species_data['bill_length_mm'].std() / species_data['bill_length_mm'].mean()) * 100
    cv_flipper = (species_data['flipper_length_mm'].std() / species_data['flipper_length_mm'].mean()) * 100
    cv_average = np.mean([cv_mass, cv_bill, cv_flipper])
    
    uniformity_data.append({
        'Espécie': species,
        'CV Massa (%)': f"{cv_mass:.1f}%",
        'CV Bico (%)': f"{cv_bill:.1f}%",
        'CV Nadadeira (%)': f"{cv_flipper:.1f}%",
        'CV Médio (%)': f"{cv_average:.1f}%"
    })

uniformity_df = pd.DataFrame(uniformity_data)
uniformity_df.sort_values('CV Médio (%)')
Espécie CV Massa (%) CV Bico (%) CV Nadadeira (%) CV Médio (%)
1 Gentoo 9.8% 6.5% 3.0% 6.5%
2 Chinstrap 10.3% 6.8% 3.6% 6.9%
0 Adelie 12.4% 6.9% 3.4% 7.6%

3. Coeficiente de Variação: Comparando Apples to Apples

O CV permite comparar variabilidade entre características com unidades diferentes.

Coeficiente de Variação: Comparando Características

O CV permite comparar variabilidade entre medidas com unidades diferentes, revelando quais características são mais variáveis.

# Calcular CV para todas as características
characteristics = {
    'body_mass_g': 'Massa corporal',
    'bill_length_mm': 'Comprimento do bico',
    'bill_depth_mm': 'Profundidade do bico',
    'flipper_length_mm': 'Comprimento da nadadeira',
    'bill_ratio': 'Razão do bico'
}

cv_data = []
for var, description in characteristics.items():
    mean_val = penguins[var].mean()
    std_val = penguins[var].std()
    cv = (std_val / mean_val) * 100
    
    # Interpretação
    if cv < 10:
        interpretation = "Baixa variabilidade"
    elif cv < 20:
        interpretation = "Variabilidade moderada"
    else:
        interpretation = "Alta variabilidade"
    
    cv_data.append({
        'Característica': description,
        'CV (%)': f"{cv:.1f}%",
        'Interpretação': interpretation
    })

cv_df = pd.DataFrame(cv_data)
cv_df.sort_values('CV (%)', ascending=False)
Característica CV (%) Interpretação
3 Comprimento da nadadeira 7.0% Baixa variabilidade
0 Massa corporal 19.1% Variabilidade moderada
4 Razão do bico 19.0% Variabilidade moderada
1 Comprimento do bico 12.4% Variabilidade moderada
2 Profundidade do bico 11.5% Variabilidade moderada

Dimorfismo na Variabilidade por Sexo

Analisamos se machos e fêmeas apresentam diferentes níveis de variabilidade na massa corporal.

# Comparar CV entre sexos
sex_variability_data = []
for sex in penguins['sex'].unique():
    sex_data = penguins[penguins['sex'] == sex]['body_mass_g']
    mean_val = sex_data.mean()
    std_val = sex_data.std() 
    cv = (std_val / mean_val) * 100
    
    sex_variability_data.append({
        'Sexo': sex.title(),
        'Média (g)': f"{mean_val:.0f}",
        'Desvio Padrão (g)': f"{std_val:.0f}",
        'CV (%)': f"{cv:.1f}%"
    })

sex_variability_df = pd.DataFrame(sex_variability_data)
sex_variability_df
Sexo Média (g) Desvio Padrão (g) CV (%)
0 Male 4546 788 17.3%
1 Female 3862 666 17.2%

Medidas de Posição: Onde Está Cada Pinguim no Ranking?

Quartis e Percentis: Posicionamento dos Pinguins

Os quartis dividem os pinguins em quatro grupos iguais, revelando como cada espécie se distribui no ranking de massa corporal.

# Calcular quartis da massa corporal
Q1 = penguins['body_mass_g'].quantile(0.25)
Q2 = penguins['body_mass_g'].quantile(0.50)  # Mediana
Q3 = penguins['body_mass_g'].quantile(0.75)

quartiles_summary = pd.DataFrame({
    'Quartil': ['Q1 (25% menores)', 'Q2 (Mediana)', 'Q3 (75% menores)', 'Q4 (25% maiores)'],
    'Limite (g)': [f"Até {Q1:.0f}", f"{Q2:.0f}", f"Até {Q3:.0f}", f"Acima de {Q3:.0f}"]
})

quartiles_summary
Quartil Limite (g)
0 Q1 (25% menores) Até 3550
1 Q2 (Mediana) 4050
2 Q3 (75% menores) Até 4775
3 Q4 (25% maiores) Acima de 4775
# Distribuição das espécies por quartis de massa
penguins_with_quartiles = penguins.copy()
penguins_with_quartiles['mass_quartile'] = pd.qcut(penguins_with_quartiles['body_mass_g'], 
                                                  q=4, labels=['Q1', 'Q2', 'Q3', 'Q4'])

quartile_by_species = pd.crosstab(penguins_with_quartiles['species'], 
                                 penguins_with_quartiles['mass_quartile'])
quartile_by_species
mass_quartile Q1 Q2 Q3 Q4
species
Adelie 64 50 32 0
Chinstrap 22 35 10 1
Gentoo 0 1 36 82

A distribuição por quartis revela clara segregação por tamanho: Adelie dominam os quartis inferiores (Q1 e Q2), Gentoo concentram-se nos superiores (Q3 e Q4), enquanto Chinstrap distribuem-se principalmente nos quartis médios. Isso confirma hierarquias de tamanho distintas entre as espécies.

Percentis Biologicamente Relevantes

Percentis específicos nos ajudam a identificar grupos extremos que podem representar juvenis, adultos dominantes ou valores típicos.

# Calcular percentis para massa corporal e comprimento do bico
percentiles_data = []
percentiles_of_interest = [5, 10, 25, 50, 75, 90, 95]

for var in ['body_mass_g', 'bill_length_mm']:
    var_name = 'Massa Corporal (g)' if var == 'body_mass_g' else 'Comprimento Bico (mm)'
    percentile_values = penguins[var].quantile([p/100 for p in percentiles_of_interest])
    
    for p, value in zip(percentiles_of_interest, percentile_values):
        if p == 5:
            interpretation = "5% menores"
        elif p == 95:
            interpretation = "5% maiores"
        elif p == 50:
            interpretation = "Mediana"
        else:
            interpretation = f"{p}º percentil"
            
        percentiles_data.append({
            'Variável': var_name,
            'Percentil': f"P{p}",
            'Valor': f"{value:.1f}",
            'Interpretação': interpretation
        })

percentiles_df = pd.DataFrame(percentiles_data)
percentiles_df
Variável Percentil Valor Interpretação
0 Massa Corporal (g) P5 3150.0 5% menores
1 Massa Corporal (g) P10 3300.0 10º percentil
2 Massa Corporal (g) P25 3550.0 25º percentil
3 Massa Corporal (g) P50 4050.0 Mediana
4 Massa Corporal (g) P75 4775.0 75º percentil
5 Massa Corporal (g) P90 5440.0 90º percentil
6 Massa Corporal (g) P95 5670.0 5% maiores
7 Comprimento Bico (mm) P5 35.7 5% menores
8 Comprimento Bico (mm) P10 36.6 10º percentil
9 Comprimento Bico (mm) P25 39.5 25º percentil
10 Comprimento Bico (mm) P50 44.5 Mediana
11 Comprimento Bico (mm) P75 48.6 75º percentil
12 Comprimento Bico (mm) P90 50.8 90º percentil
13 Comprimento Bico (mm) P95 52.0 5% maiores

Forma das Distribuições: Como São as “Curvas” dos Pinguins?

Assimetria: Balanceamento das Distribuições

A assimetria revela se as distribuições são balanceadas ou apresentam caudas estendidas, indicando possíveis subgrupos ou pressões evolutivas.

# Analisar assimetria das principais variáveis morfológicas
variables_to_analyze = {
    'body_mass_g': 'Massa corporal',
    'bill_length_mm': 'Comprimento do bico',
    'bill_depth_mm': 'Profundidade do bico',
    'flipper_length_mm': 'Comprimento da nadadeira'
}

skewness_data = []
for var, description in variables_to_analyze.items():
    skewness = stats.skew(penguins[var])
    
    if abs(skewness) < 0.5:
        interpretation = "Simétrica"
    elif skewness > 0.5:
        interpretation = "Assimétrica à direita"
    elif skewness < -0.5:
        interpretation = "Assimétrica à esquerda"
    
    # Implicação biológica
    if abs(skewness) > 0.5:
        biological_implication = "Possíveis subgrupos"
    else:
        biological_implication = "Distribuição balanceada"
    
    skewness_data.append({
        'Variável': description,
        'Assimetria': f"{skewness:.3f}",
        'Interpretação': interpretation,
        'Implicação Biológica': biological_implication
    })

skewness_df = pd.DataFrame(skewness_data)
skewness_df
Variável Assimetria Interpretação Implicação Biológica
0 Massa corporal 0.470 Simétrica Distribuição balanceada
1 Comprimento do bico 0.045 Simétrica Distribuição balanceada
2 Profundidade do bico -0.149 Simétrica Distribuição balanceada
3 Comprimento da nadadeira 0.359 Simétrica Distribuição balanceada

Curtose: Concentração das Distribuições

A curtose indica se as distribuições têm valores concentrados no centro (pontiaguda) ou dispersos (achatada).

# Analisar curtose das variáveis morfológicas
kurtosis_data = []
for var, description in variables_to_analyze.items():
    kurt = stats.kurtosis(penguins[var])
    
    if kurt > 0:
        interpretation = "Leptocúrtica (concentrada)"
    elif kurt < 0:
        interpretation = "Platicúrtica (dispersa)"
    else:
        interpretation = "Mesocúrtica (normal)"
    
    kurtosis_data.append({
        'Variável': description,
        'Curtose': f"{kurt:.3f}",
        'Interpretação': interpretation
    })

kurtosis_df = pd.DataFrame(kurtosis_data)
kurtosis_df
Variável Curtose Interpretação
0 Massa corporal -0.740 Platicúrtica (dispersa)
1 Comprimento do bico -0.888 Platicúrtica (dispersa)
2 Profundidade do bico -0.897 Platicúrtica (dispersa)
3 Comprimento da nadadeira -0.965 Platicúrtica (dispersa)

Tabelas de Frequência: Contando e Comparando Pinguins

Distribuição das Espécies

# Frequência e proporções por espécie
species_freq = penguins['species'].value_counts()
species_prop = penguins['species'].value_counts(normalize=True)

species_table = pd.DataFrame({
    'Frequência': species_freq,
    'Proporção': species_prop.round(3),
    'Percentual': (species_prop * 100).round(1).astype(str) + '%'
})

species_table
Frequência Proporção Percentual
species
Adelie 146 0.438 43.8%
Gentoo 119 0.357 35.7%
Chinstrap 68 0.204 20.4%

Distribuição Geográfica: Espécies por Ilha

A tabela cruzada revela padrões de distribuição geográfica das espécies nas ilhas do arquipélago Palmer.

# Tabela cruzada espécie vs ilha com totais
cross_table = pd.crosstab(penguins['species'], penguins['island'], margins=True)
cross_table
island Biscoe Dream Torgersen All
species
Adelie 44 55 47 146
Chinstrap 0 68 0 68
Gentoo 119 0 0 119
All 163 123 47 333
# Proporções por espécie (distribuição geográfica de cada espécie)
props_by_species = pd.crosstab(penguins['species'], penguins['island'], normalize='index')
geographic_distribution = (props_by_species * 100).round(1)
geographic_distribution.columns = [f"{col} (%)" for col in geographic_distribution.columns]
geographic_distribution
Biscoe (%) Dream (%) Torgersen (%)
species
Adelie 30.1 37.7 32.2
Chinstrap 0.0 100.0 0.0
Gentoo 100.0 0.0 0.0

A distribuição geográfica revela padrões ecológicos distintos: Adelie são generalistas (presentes nas 3 ilhas), Chinstrap são especialistas extremos (100% em Dream), e Gentoo são especialistas de Biscoe (100%). Isso sugere diferentes requisitos ambientais e estratégias de ocupação do habitat.

Distribuição por Faixas de Massa Corporal

Agrupamos os pinguins em categorias de massa biologicamente significativas para identificar padrões de distribuição de tamanho.

# Criar faixas de massa corporal biologicamente relevantes
mass_bins = [2500, 3500, 4500, 5500, 6500]
mass_labels = ['Leve (2.5-3.5kg)', 'Médio (3.5-4.5kg)', 'Pesado (4.5-5.5kg)', 'Muito Pesado (5.5-6.5kg)']
mass_categories = pd.cut(penguins['body_mass_g'], bins=mass_bins, labels=mass_labels)

# Tabela de frequência com frequências acumuladas
mass_freq = mass_categories.value_counts().sort_index()
mass_prop = mass_categories.value_counts(normalize=True).sort_index()

mass_freq_table = pd.DataFrame({
    'Frequência': mass_freq,
    'Percentual (%)': (mass_prop * 100).round(1),
    'Freq. Acumulada': mass_freq.cumsum(),
    'Perc. Acumulado (%)': (mass_prop.cumsum() * 100).round(1)
})

mass_freq_table
Frequência Percentual (%) Freq. Acumulada Perc. Acumulado (%)
body_mass_g
Leve (2.5-3.5kg) 75 22.5 75 22.5
Médio (3.5-4.5kg) 146 43.8 221 66.4
Pesado (4.5-5.5kg) 84 25.2 305 91.6
Muito Pesado (5.5-6.5kg) 28 8.4 333 100.0

A distribuição mostra concentração nas faixas médias: 66% dos pinguins pesam entre 3.5-4.5kg. Apenas 8% são “muito pesados” (>5.5kg), provavelmente Gentoo machos, enquanto 23% são “leves” (<3.5kg), possivelmente Adelie fêmeas. Esta distribuição reflete a diversidade de tamanhos entre espécies e sexos.

Análise de Dimorfismo por Espécie

Examinamos como machos e fêmeas se distribuem nas categorias de massa corporal dentro de cada espécie.

# Análise de dimorfismo por espécie
dimorphism_analysis = []

for species in penguins['species'].unique():
    species_data = penguins[penguins['species'] == species]
    
    # Criar categorias de massa específicas para esta espécie
    species_mass_cats = pd.cut(species_data['body_mass_g'], bins=3, labels=['Pequeno', 'Médio', 'Grande'])
    
    # Tabela cruzada sexo vs categoria de massa
    sex_mass_table = pd.crosstab(species_data['sex'], species_mass_cats)
    
    # Calcular proporções para interpretação
    props = pd.crosstab(species_data['sex'], species_mass_cats, normalize='index')
    female_large = props.loc['female', 'Grande'] * 100 if 'female' in props.index else 0
    male_large = props.loc['male', 'Grande'] * 100 if 'male' in props.index else 0
    
    dimorphism_analysis.append({
        'Espécie': species,
        'Fêmeas Grandes (%)': f"{female_large:.1f}%",
        'Machos Grandes (%)': f"{male_large:.1f}%",
        'Dimorfismo': "Machos maiores" if male_large > female_large else "Fêmeas maiores"
    })

dimorphism_df = pd.DataFrame(dimorphism_analysis)
dimorphism_df
Espécie Fêmeas Grandes (%) Machos Grandes (%) Dimorfismo
0 Adelie 0.0% 39.7% Machos maiores
1 Gentoo 0.0% 45.9% Machos maiores
2 Chinstrap 2.9% 23.5% Machos maiores

Os resultados mostram dimorfismo sexual claro em todas as espécies, mas com intensidades diferentes. Adelie apresentam o padrão mais extremo, com nenhuma fêmea classificada como “grande” versus 40% dos machos. Gentoo e Chinstrap mostram padrões similares, mas menos acentuados.

Resumo Estatístico Final

Visão Geral do Dataset

# Resumo geral dos dados
dataset_summary = pd.DataFrame({
    'Métrica': ['Total de pinguins', 'Número de espécies', 'Número de ilhas', 'Período de coleta', 'Proporção macho/fêmea'],
    'Valor': [
        f"{len(penguins)} indivíduos",
        f"{penguins['species'].nunique()} ({', '.join(penguins['species'].unique())})",
        f"{penguins['island'].nunique()} ({', '.join(penguins['island'].unique())})",
        f"{penguins['year'].min()}-{penguins['year'].max()}",
        f"{(penguins['sex'].value_counts(normalize=True)['male']*100):.0f}% / {(penguins['sex'].value_counts(normalize=True)['female']*100):.0f}%"
    ]
})

dataset_summary
Métrica Valor
0 Total de pinguins 333 indivíduos
1 Número de espécies 3 (Adelie, Gentoo, Chinstrap)
2 Número de ilhas 3 (Torgersen, Biscoe, Dream)
3 Período de coleta 2007-2009
4 Proporção macho/fêmea 50% / 50%

Perfil Estatístico por Espécie

# Criar perfil completo por espécie
species_profiles = []

for species in penguins['species'].unique():
    species_data = penguins[penguins['species'] == species]
    
    # Calcular dimorfismo se ambos sexos presentes
    dimorphism = "N/A"
    if len(species_data['sex'].unique()) == 2:
        male_mass = species_data[species_data['sex'] == 'male']['body_mass_g'].mean()
        female_mass = species_data[species_data['sex'] == 'female']['body_mass_g'].mean()
        dimorphism = f"{male_mass/female_mass:.2f}x"
    
    species_profiles.append({
        'Espécie': species,
        'N': len(species_data),
        'Massa (g)': f"{species_data['body_mass_g'].mean():.0f}±{species_data['body_mass_g'].std():.0f}",
        'Bico L×P (mm)': f"{species_data['bill_length_mm'].mean():.1f}×{species_data['bill_depth_mm'].mean():.1f}",
        'Razão Bico': f"{species_data['bill_ratio'].mean():.2f}",
        'Dimorfismo M/F': dimorphism
    })

species_profile_df = pd.DataFrame(species_profiles)
species_profile_df
Espécie N Massa (g) Bico L×P (mm) Razão Bico Dimorfismo M/F
0 Adelie 146 3706±459 38.8×18.3 2.12 1.20x
1 Gentoo 119 5092±501 47.6×15.0 3.18 1.17x
2 Chinstrap 68 3733±384 48.8×18.4 2.65 1.12x

Principais Insights Descobertos

Através das estatísticas descritivas, revelamos padrões fascinantes sobre os pinguins antárticos:

🐧 Hierarquia de Tamanho: Gentoo são os maiores (5092g em média), seguidos por Chinstrap (3733g) e Adelie (3706g) - uma diferença de quase 40% entre extremos.

🦆 Especialização Alimentar: Gentoo possuem bicos mais alongados (maior razão comprimento/profundidade), indicando adaptação para peixes e lulas, enquanto outras espécies têm bicos mais robustos para krill.

📊 Variabilidade: Adelie apresentam maior diversidade interna, possivelmente devido à distribuição em múltiplas ilhas com condições ambientais variadas.

🗺️ Distribuição Geográfica: Adelie são cosmopolitas (presentes nas 3 ilhas), enquanto Chinstrap e Gentoo são endêmicas de Dream e Biscoe, respectivamente.

⚖️ Dimorfismo Sexual: Todas as espécies apresentam dimorfismo, com machos consistentemente maiores que fêmeas, refletindo estratégias reprodutivas típicas de aves marinhas.

Conclusão

Estatísticas descritivas transformaram nossos pinguins de meros registros em histórias quantitativas: descobrimos que Gentoos são 40% maiores que Adelies, que o dimorfismo sexual varia por espécie, e que cada espécie tem especialização alimentar distinta.

DicaO que Dominamos Neste Módulo

Medidas centrais que revelam o “pinguim típico” de cada espécie
Medidas de dispersão que quantificam diversidade intra-espécie
Medidas de posição que ranqueiam indivíduos em suas populações
Análise de forma que detecta assimetrias biológicas
Tabelas de frequência que mapeiam distribuições categóricas
Interpretação biológica de cada estatística calculada

Agora temos fundamentos quantitativos sólidos para criar visualizações impactantes no próximo módulo!

Recursos Adicionais