library(reticulate)#abrindo o pacote reticulate
Desafio 11
virtualenv_create("env_me315", python = "C:/Program Files/Python312/python.exe")#criando um ambiente virtual pra usar python
virtualenv: env_me315
use_virtualenv("env_me315", required = TRUE) #manda usar o ambiente virtual criado
#!pip install polars
#!pip install fastexcel
#importando o polars
import polars as pl
##1
# 1️⃣ Ler CSV rapidamente sem cabeçalho
= pl.read_csv("renda_adulta.csv.gz", has_header = False, null_values="?") df
# 2️⃣ Definir os nomes das colunas
= [
colunas "age", "workclass", "fnlwgt", "education", "education-num",
"marital-status", "occupation", "relationship", "race", "sex",
"capital-gain", "capital-loss", "hours-per-week", "native-country",
"income"
]
#definindo as colunas
= colunas df.columns
# 3️⃣ Converter tipos das colunas
= {
tipos "age": pl.Int64,
"workclass": pl.Categorical,
"fnlwgt": pl.Int64,
"education": pl.Categorical,
"education-num": pl.Int64,
"marital-status": pl.Categorical,
"occupation": pl.Categorical,
"relationship": pl.Categorical,
"race": pl.Categorical,
"sex": pl.Categorical,
"capital-gain": pl.Int64,
"capital-loss": pl.Int64,
"hours-per-week": pl.Int64,
"native-country": pl.Categorical,
"income": pl.Categorical
}
= df.with_columns([df[col].cast(tipo).alias(col) for col, tipo in tipos.items()]) # Converte cada coluna para o tipo definido em 'tipos' e mantém os nomes df
print(df.head()) #mostra o inicio do df
shape: (5, 15)
┌─────┬──────────────┬────────┬───────────┬───┬──────────────┬──────────────┬─────────────┬────────┐
│ age ┆ workclass ┆ fnlwgt ┆ education ┆ … ┆ capital-loss ┆ hours-per-we ┆ native-coun ┆ income │
│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ --- ┆ ek ┆ try ┆ --- │
│ i64 ┆ cat ┆ i64 ┆ cat ┆ ┆ i64 ┆ --- ┆ --- ┆ cat │
│ ┆ ┆ ┆ ┆ ┆ ┆ i64 ┆ cat ┆ │
╞═════╪══════════════╪════════╪═══════════╪═══╪══════════════╪══════════════╪═════════════╪════════╡
│ 39 ┆ State-gov ┆ 77516 ┆ Bachelors ┆ … ┆ 0 ┆ 40 ┆ United-Stat ┆ <=50K │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ es ┆ │
│ 50 ┆ Self-emp-not ┆ 83311 ┆ Bachelors ┆ … ┆ 0 ┆ 13 ┆ United-Stat ┆ <=50K │
│ ┆ -inc ┆ ┆ ┆ ┆ ┆ ┆ es ┆ │
│ 38 ┆ Private ┆ 215646 ┆ HS-grad ┆ … ┆ 0 ┆ 40 ┆ United-Stat ┆ <=50K │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ es ┆ │
│ 53 ┆ Private ┆ 234721 ┆ 11th ┆ … ┆ 0 ┆ 40 ┆ United-Stat ┆ <=50K │
│ ┆ ┆ ┆ ┆ ┆ ┆ ┆ es ┆ │
│ 28 ┆ Private ┆ 338409 ┆ Bachelors ┆ … ┆ 0 ┆ 40 ┆ Cuba ┆ <=50K │
└─────┴──────────────┴────────┴───────────┴───┴──────────────┴──────────────┴─────────────┴────────┘
##2
# Mostrar os tipos de cada coluna
for col, dtype in zip(df.columns, df.dtypes):
print(f"{col}: {dtype}")
age: Int64
workclass: Categorical
fnlwgt: Int64
education: Categorical
education-num: Int64
marital-status: Categorical
occupation: Categorical
relationship: Categorical
race: Categorical
sex: Categorical
capital-gain: Int64
capital-loss: Int64
hours-per-week: Int64
native-country: Categorical
income: Categorical
##3
# Dimensões do DataFrame
= df.shape #tamanho do df
linhas, colunas print(f"Número de linhas: {linhas}")
Número de linhas: 32561
print(f"Número de colunas: {colunas}")
Número de colunas: 15
print(f"Logo a dimentao é {linhas} x {colunas}")
Logo a dimentao é 32561 x 15
##4
# Contagem de pessoas por faixa de renda
= df.filter(df["income"] == ">50K").height
acima_50k = df.filter(df["income"] == "<=50K").height
abaixo_50k
print(f"Pessoas que ganham acima de $50.000: {acima_50k}")
Pessoas que ganham acima de $50.000: 7841
print(f"Pessoas que ganham abaixo ou igual a $50.000: {abaixo_50k}")
Pessoas que ganham abaixo ou igual a $50.000: 24720
##5
import polars as pl
# Renomear as colunas wide para 'gain' e 'loss' para simplificar o melt
= df.rename({
df_renomeado "capital-gain": "gain",
"capital-loss": "loss"
})
# Transformar as colunas 'gain' e 'loss' de formato wide para longo
= df_renomeado.unpivot(
renda_longo =[col for col in df_renomeado.columns if col not in ["gain", "loss"]], # mantém todas as outras colunas como identificadores
index=["gain", "loss"], # colunas que serão convertidas em formato longo
on="tipo", # nome da coluna que indicará o tipo ('gain' ou 'loss')
variable_name="Valor" # nome da coluna que armazenará os valores
value_name
)
# Exibir as primeiras linhas do DataFrame longo para verificar o resultado
print(renda_longo.head())
shape: (5, 15)
┌─────┬──────────────────┬────────┬───────────┬───┬────────────────┬────────┬──────┬───────┐
│ age ┆ workclass ┆ fnlwgt ┆ education ┆ … ┆ native-country ┆ income ┆ tipo ┆ Valor │
│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ cat ┆ i64 ┆ cat ┆ ┆ cat ┆ cat ┆ str ┆ i64 │
╞═════╪══════════════════╪════════╪═══════════╪═══╪════════════════╪════════╪══════╪═══════╡
│ 39 ┆ State-gov ┆ 77516 ┆ Bachelors ┆ … ┆ United-States ┆ <=50K ┆ gain ┆ 2174 │
│ 50 ┆ Self-emp-not-inc ┆ 83311 ┆ Bachelors ┆ … ┆ United-States ┆ <=50K ┆ gain ┆ 0 │
│ 38 ┆ Private ┆ 215646 ┆ HS-grad ┆ … ┆ United-States ┆ <=50K ┆ gain ┆ 0 │
│ 53 ┆ Private ┆ 234721 ┆ 11th ┆ … ┆ United-States ┆ <=50K ┆ gain ┆ 0 │
│ 28 ┆ Private ┆ 338409 ┆ Bachelors ┆ … ┆ Cuba ┆ <=50K ┆ gain ┆ 0 │
└─────┴──────────────────┴────────┴───────────┴───┴────────────────┴────────┴──────┴───────┘
##6
# Calcula a média de horas trabalhadas por semana agrupando pelo nível salarial ('income')
= df.group_by("income").agg(
media_horas "hours-per-week").mean().alias("media_horas") # calcula a média da coluna 'hours-per-week' e renomeia para 'media_horas'
pl.col(
)
# Exibe o resultado com a média de horas por classe salarial
print(media_horas)
shape: (2, 2)
┌────────┬─────────────┐
│ income ┆ media_horas │
│ --- ┆ --- │
│ cat ┆ f64 │
╞════════╪═════════════╡
│ >50K ┆ 45.473026 │
│ <=50K ┆ 38.84021 │
└────────┴─────────────┘
##7
# Conta quantas pessoas existem em cada profissão
= (
contagem_profissao "occupation") # agrupa o DataFrame pela coluna 'occupation'
df.group_by(
.agg(len().alias("num_pessoas") # conta o número de linhas em cada grupo e renomeia para 'num_pessoas'
pl.
)"num_pessoas", descending=True) # ordena as profissões do maior para o menor número de pessoas
.sort(
)
# Exibe a contagem de pessoas por profissão
print(contagem_profissao)
shape: (15, 2)
┌─────────────────┬─────────────┐
│ occupation ┆ num_pessoas │
│ --- ┆ --- │
│ cat ┆ u32 │
╞═════════════════╪═════════════╡
│ Prof-specialty ┆ 4140 │
│ Craft-repair ┆ 4099 │
│ Exec-managerial ┆ 4066 │
│ Adm-clerical ┆ 3770 │
│ Sales ┆ 3650 │
│ … ┆ … │
│ Farming-fishing ┆ 994 │
│ Tech-support ┆ 928 │
│ Protective-serv ┆ 649 │
│ Priv-house-serv ┆ 149 │
│ Armed-Forces ┆ 9 │
└─────────────────┴─────────────┘
##8
#!pip install matplotlib
import matplotlib
"Agg") # Define o backend 'Agg', que não depende do Tkinter, útil para gerar gráficos em RMarkdown/HTML
matplotlib.use(
import matplotlib.pyplot as plt # Importa a interface pyplot do Matplotlib para criar gráficos
# Calcula a média de horas trabalhadas por semana agrupando pelo nível salarial ('income')
= df.group_by("income").agg(
media_horas "hours-per-week").mean().alias("media_horas") # calcula a média da coluna 'hours-per-week' e renomeia para 'media_horas'
pl.col(
)
# Extrai os nomes das classes salariais e os valores médios diretamente do Polars para plotagem
= media_horas["income"].to_list() # lista com as categorias de 'income'
classes = media_horas["media_horas"].to_list() # lista com as médias correspondentes
valores
# Criar gráfico de barras usando Matplotlib
=(8,5)) # define o tamanho da figura
plt.figure(figsize=['skyblue', 'salmon']) # cria barras com cores diferentes para cada classe
plt.bar(classes, valores, color"Média de Horas Trabalhadas por Semana por Classe Salarial") # título do gráfico
plt.title("Classe Salarial") # rótulo do eixo x
plt.xlabel("Horas Semanais Médias") # rótulo do eixo y
plt.ylabel(0, max(valores) + 5) # ajusta o limite superior do eixo y para melhor visualização plt.ylim(
(0.0, 50.473026399693914)
# exibe o gráfico plt.show()
##Desafio
# Contagem total de pessoas por gênero
= df.group_by("sex").agg(
total_por_genero len().alias("total") # conta o número de linhas por gênero e renomeia para 'total'
pl.
)
# Contagem de pessoas com income >50K por gênero
= df.filter(df["income"] == ">50K").group_by("sex").agg(
acima_50k_por_genero len().alias("acima_50k") # conta o número de pessoas ganhando acima de 50K por gênero
pl.
)
# Juntar os resultados e calcular a porcentagem de pessoas com income >50K
= total_por_genero.join(acima_50k_por_genero, on="sex", how="left").with_columns(
distribuicao_genero "acima_50k") / pl.col("total") * 100).alias("perc_acima_50k") # calcula a proporção em porcentagem
(pl.col(
)
# Exibe a tabela com total, acima de 50K e porcentagem por gênero
print(distribuicao_genero)
shape: (2, 4)
┌────────┬───────┬───────────┬────────────────┐
│ sex ┆ total ┆ acima_50k ┆ perc_acima_50k │
│ --- ┆ --- ┆ --- ┆ --- │
│ cat ┆ u32 ┆ u32 ┆ f64 │
╞════════╪═══════╪═══════════╪════════════════╡
│ Female ┆ 10771 ┆ 1179 ┆ 10.946059 │
│ Male ┆ 21790 ┆ 6662 ┆ 30.573658 │
└────────┴───────┴───────────┴────────────────┘
# Comentário final interpretativo sobre a disparidade salarial observada
print("logo, há evidência de disparidade salarial entre gêneros biológicos neste dataset, pois A proporção de homens ganhando acima de 50K é quase 3 vezes maior que a das mulheres como mostram os dados")
logo, há evidência de disparidade salarial entre gêneros biológicos neste dataset, pois A proporção de homens ganhando acima de 50K é quase 3 vezes maior que a das mulheres como mostram os dados
##horario do html
# Captura o horário atual
<- Sys.time()
horario_geracao
# Mostrar no console
horario_geracao
[1] "2025-10-07 11:12:37 -03"
# Ou inserir em um HTML (exemplo com cat)
cat("<p>Relatório gerado em:", horario_geracao, "</p>")
<p>Relatório gerado em: 1759846357 </p>