<jupyter_start><jupyter_text>MAT281 -  Operaciones groupby con pandas  Objetivos de la clase* Aprender sobre las operaciones *groupby* con pandas.  Contenidos* [Operaciones: Groupby](c1)  I.- Operaciones: Groupby **Groupby** es un concepto bastante simple. Podemos crear una agrupación de categorías y aplicar una función a las categorías. El proceso de groupby se puede resumiren los siguientes pasos:* **División**: es un proceso en el que dividimos los datos en grupos aplicando algunas condiciones en los conjuntos de datos.* **Aplicación**: es un proceso en el que aplicamos una función a cada grupo de forma independiente* **Combinación**: es un proceso en el que combinamos diferentes conjuntos de datos después de aplicar groupby y resultados en una estructura de datos  Después de dividir los datos en un grupo, aplicamos una función a cada grupo para realizar algunas operaciones que son:* **Agregación**: es un proceso en el que calculamos una estadística resumida (o estadística) sobre cada grupo. Por ejemplo, Calcular sumas de grupo o medios* **Transformación**: es un proceso en el que realizamos algunos cálculos específicos del grupo y devolvemos un índice similar. Por ejemplo, llenar NA dentro de grupos con un valor derivado de cada grupo* **Filtración**: es un proceso en el cual descartamos algunos grupos, de acuerdo con un cálculo grupal que evalúa Verdadero o Falso. Por ejemplo, Filtrar datos en función de la suma o media grupal Para comprender mejor el concepto de agrupación de tablas, se realiza un ejercicio simple sobre el conjunto de datos **pokemon.csv**<jupyter_code># libreria
import pandas as pd
import numpy as np
import os
# cargar datos
pokemon_data = pd.read_csv(os.path.join("data","pokemon.csv"), sep=",")
pokemon_data.head()
# renombrar columnas
pokemon_data.columns = pokemon_data.columns.str.lower().str.replace('.','_').str.replace(' ','_') #change into upper case
pokemon_data.head()<jupyter_output><empty_output><jupyter_text>a ) Número de pokemones por generación<jupyter_code>grupo = pokemon_data.groupby('generation')  
grupo[['name']].count().reset_index()<jupyter_output><empty_output><jupyter_text>b) Número de pokemones  por par Tipo I y Tipo II<jupyter_code>grupo = pokemon_data.groupby(['type_1','type_2']) 
grupo['name'].count().reset_index()<jupyter_output><empty_output><jupyter_text>c) Calcular hp promedio y hp total agrupados si el pokemon es legendario o no  método 01: ocupando el comando agg<jupyter_code># metodo 01: ocupando el comando agg
grupo = pokemon_data.groupby(['legendary'])
df_leng = grupo.agg({'hp':[np.mean,sum]}).reset_index()
df_leng<jupyter_output><empty_output><jupyter_text>método 02: ocupando el comando apply<jupyter_code># metodo 02: ocupando el comando apply
def my_custom_function(x):
        """
        Funcion que calcula el hp promedio y total
        """
        names = {
        'mean': x['hp'].mean(),
        'sum':x['hp'].sum()}
        
        return pd.Series(names, index=['mean', 'sum'])
grupo = pokemon_data.groupby(['legendary'])
df_leng = grupo.apply(my_custom_function).reset_index()
df_leng<jupyter_output><empty_output><jupyter_text>d) Normalizar las estadísticas agrupados por generación<jupyter_code>cols_statistics = [
    'generation', 'hp', 
    'attack', 'defense',
    'sp__atk','sp__def', 
    'speed'
]

grupo = pokemon_data[cols_statistics].groupby('generation') 
sc = lambda x: (x - x.mean()) / x.std()
grupo.transform(sc)<jupyter_output><empty_output><jupyter_text>e) Identificar generaciones  que tienen menos de 100 pokemones<jupyter_code>grupo = pokemon_data[['name','generation']].groupby('generation')  
grupo.filter(lambda x: len(x['name']) < 150)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10628540598867009, 'fraction_numerical': 0.005395198273536552, 'mean_word_length': 5.657091561938959, 'pattern_counts': {'":': 0, '<': 30, '<?xml version=': 0, '>': 29, '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': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '46605', 'license': 'MIT', 'n_tokens_mistral': 1276, 'n_tokens_neox': 1251, 'n_words': 383, 'path': 'labs/04_modulos_pandas/02_pandas_groupby.ipynb', 'repo_name': 'Pipeuaps/mat281_portfolio', 'size': '3707'}