<jupyter_start><jupyter_text>Laboratorio 4<jupyter_code>import pandas as pd
from pathlib import Path<jupyter_output><empty_output><jupyter_text>Utilizarás el conjunto de datos de pokemon.<jupyter_code>pkm = (
    pd.read_csv(Path().resolve().parent / "data" / "pokemon.csv", index_col="#")
    .rename(columns=lambda x: x.replace(" ", "").replace(".", "_").lower())
)
pkm.head()<jupyter_output><empty_output><jupyter_text>Ejercicio 1(1 pto)Agrupar por `generation` y `legendary` y obtener por grupo:* Promedio de `hp`* Mínimo y máximo de `sp_atk` y `sp_def`<jupyter_code>pkm.groupby(["generation", "legendary"]).agg(hp_mean=("hp","mean"), sp_atk_min = ("sp_atk","min"), sp_atk_max=("sp_atk","max"), sp_def_min=("sp_def","min"),sp_def_max=("sp_def","max"))<jupyter_output><empty_output><jupyter_text>Ejercicio 2(1 pto)El profesor Oakgueda determinó que una buen indicador de pokemones es: $$ 0.2 \, \textrm{hp} + 0.4 \,(\textrm{attack} + \textrm{sp_atk})^2 + 0.3 \,( \textrm{defense} + \textrm{sp_deff})^{1.5} + 0.1 \, \textrm{speed}$$Según este indicador, ¿Qué grupo de pokemones (`type1`, `type2`) es en promedio mejor que el resto?<jupyter_code>def oakgueda_indicator(df):
    oakgueda_ind = df.loc[:,"hp"]*0.2+0.4*(df.loc[:,"attack"]+df.loc[:,"sp_atk"])**2+0.3*(df.loc[:,"defense"]+df.loc[:,"sp_def"])**1.5+0.1*df.loc[:,"speed"]
    return oakgueda_ind
max_ = pkm.assign( oak_ind = lambda df: oakgueda_indicator(df)).groupby(["type1","type2"])["oak_ind"].mean().loc[:,lambda df: df == df.max()]
print(f"En promedio, los pokemones {max_.keys()[0][0]}-{max_.keys()[0][1]} son los mejores según el indicador del profesor Oakgueda, con {round(max_.iloc[0],2)} puntos.")<jupyter_output>En promedio, los pokemones Ground-Fire son los mejores según el indicador del profesor Oakgueda, con 44774.85 puntos.<jupyter_text>__Respuesta__: En promedio, los pokemones Ground-Fire son mejores según el indicador del profesor Oakgueda.  Ejercicio 3(1 pto)Define una función que escale los datos tal que, si $s$ es una columna: $$s\_scaled = \frac{s - \min(s)}{\max(s) - \min(s)}$$Y luego transforma cada columna numérica agrupando por si el pokemon es legendario o no.<jupyter_code>def minmax_scale(s):
    return (s-s.min())/(s.max()-s.min())
aux = pkm.copy()
aux[list(["hp","attack","defense","sp_atk","sp_def","speed"])] = pkm.groupby(["legendary"])[list(["hp","attack","defense","sp_atk","sp_def","speed"])].transform(minmax_scale)
display(aux)<jupyter_output><empty_output><jupyter_text>Ejercicio 4(1 pto)El profesor Oakgueda necesita saber cuántos pokemones hay luego de filtrar el dataset tal que el grupo de (`type1`, `type2`) tenga en promedio un indicador (el del ejercicio 2) mayor a 40000.<jupyter_code>filtrados = pkm.groupby(["type1","type2"]).filter(lambda df: oakgueda_indicator(df).mean()>40000)
print(f"La cantidad de pokemones cuyo indicador promedio por grupo (type1 , type2) sea superior a 40000 es: {len(filtrados)}")
pkm_filtered = "Los pokemones son :"
for pkm_ in filtrados["name"]:
    pkm_filtered += f" {pkm_},"
print(pkm_filtered.strip(","))<jupyter_output>La cantidad de pokemones cuyo indicador promedio por grupo (type1 , type2) sea superior a 40000 es: 2
Los pokemones son : Primal Groudon, Hoopa Unbound
{'fraction_non_alphanumeric': 0.17524813895781638, 'fraction_numerical': 0.024193548387096774, 'mean_word_length': 6.827669902912621, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 24, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '470366', 'license': 'MIT', 'n_tokens_mistral': 1317, 'n_tokens_neox': 1278, 'n_words': 277, 'path': 'labs/lab04.ipynb', 'repo_name': 'Konnits/mat281_portfolio', 'size': '3224'}