penguins_raw = pd.read_csv('https://raw.githubusercontent.com/allisonhorst/palmerpenguins/master/inst/extdata/penguins.csv')
penguins = penguins_raw.dropna()
glimpse(penguins)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
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?
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.
✅ 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
- Palmer Penguins Statistical Analysis - Análises estatísticas do dataset
- SciPy Stats Documentation - Funções estatísticas avançadas
- Biological Statistics - Estatísticas aplicadas à biologia
- Pandas Descriptive Statistics - Documentação oficial