es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Calcular el valor medio de las filas que tienen el mismo valor de columna en Pandas.

Estoy tratando de combinar tres DataFrames de pandas juntos.

Uno de ellos (llamado major) tiene una columna category donde cada fila tiene una etiqueta única:

A   B category

0 90 17 cat_A
1 36 81 cat_B
2 90 67 cat_C

Dos dfs más pequeños (llamados minor) contienen varias filas y tienen sus propios nombres de columna únicos. Cada df tiene una columna “category” donde cada fila tiene un valor que está presente en la columna de categoría del df principal:

Aquí hay un ejemplo de uno de esos dfs menores. La única diferencia entre ambos es que el primer df menor tiene las columnas C y D, mientras que el segundo tiene las columnas E y F.

Mi objetivo es calcular la media de los valores en los dfs menores en función de la columna de categoría, para que al final tenga los siguientes dfs:

  C      D

cat_A 89.00 23.00
cat_B 30.00 33.00
cat_C 28.75 59.25

Donde cada columna contiene la media de los valores que están en cada categoría.

Para ello, hice el siguiente código, donde creamos DataFrames vacíos con los valores de columna de los dfs menores y los índices de los diferentes valores de categorías. Luego lleno este dataframe usando un bucle for donde itero sobre cada valor del índice.

copy_dfs = {}
for k, min_df in minor_dfs.items():
    # Obtener columnas de df menor
    # Obtener índice de la categoría del df principal
    col_names = min_df.columns.values
    ind_values = major_df.category.values

    # Crear un df con columnas e índices y establecer valores en np.nan
    copy_df = pd.DataFrame(np.nan, index=ind_values, columns=col_names)
    copy_df = copy_df.drop("category", axis=1)

    # Para cada categoría en el índice del dataframe
    for maj_category in copy_df.index:
        # Seleccionar filas en df menor donde la categoría es la misma que la categoría del df principal
        minor_rows = min_df[min_df.category == maj_category]
        minor_rows = minor_rows.drop("category", axis=1)
        # Calcular los valores medios (por columna) de las filas seleccionadas
        # Agregar los valores medios en copy_df, donde el índice corresponde a la categoría del df principal
        copy_df.loc[maj_category] = minor_rows.mean()

    # Almacenar en el diccionario
    copy_dfs[k] = copy_df

Sin embargo, creo que este código podría optimizarse utilizando operaciones vectorizadas, especialmente en la parte en la que itero para cada fila. Entonces me preguntaba si había una manera más fácil e inteligente de lograr lo que estoy tratando de hacer.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Sí, de hecho hay una manera más fácil y eficiente de lograr esto utilizando las funciones merge y groupby en pandas.

    Primero, podemos combinar el dataframe principal con cada uno de los dataframes menores en la columna compartida category utilizando la función merge. Esto creará dataframes separados donde cada fila es una combinación de una fila del dataframe principal con una fila de uno de los dataframes menores que comparten la misma category.

    merged_dfs = {}
    for k, min_df in minor_dfs.items():
        merged_dfs[k] = pd.merge(major_df[['category']], min_df, on='category')
    

    Esto creará dos dataframes combinados (uno para cada dataframe menor) con columnas category, C y D para el primero o category, E y F para el segundo.

    A continuación, podemos usar la función groupby para agrupar los dataframes combinados por category y calcular la media de cada grupo utilizando la función mean.

    mean_dfs = {}
    for k, merged_df in merged_dfs.items():
        mean_df = merged_df.groupby('category').mean()
        mean_dfs[k] = mean_df.drop('category', axis=1)
    

    Esto creará dos dataframes de media (uno para cada dataframe menor) donde cada fila representa la media de los valores en cada columna para una category específica.

    Finalmente, podemos combinar ambos dataframes de media utilizando la función concat con el parámetro keys para crear un dataframe de múltiples índices.

    result_df = pd.concat(mean_dfs, axis=1, keys=mean_dfs.keys())
    

    Esto creará el dataframe de resultados esperado con columnas C, D, E y F y filas cat_A, cat_B y cat_C, donde cada valor es la media de los valores en la categoría y columna correspondiente.

               1st            2nd          
                 C     D       E      F 
    category                         
    cat_A     89.0  23.0  36.500  50.00 
    cat_B     30.0  33.0  72.500  43.50 
    cat_C     28.75  59.25  60.875  44.75
    

Comments are closed.