Tengo el siguiente python pandas marco de datos:

df = pd.DataFrame( {
   'A': [1,1,1,1,2,2,2,3,3,4,4,4],
   'B': [5,5,6,7,5,6,6,7,7,6,7,7],
   'C': [1,1,1,1,1,1,1,1,1,1,1,1]
    } );

df
    A  B  C
0   1  5  1
1   1  5  1
2   1  6  1
3   1  7  1
4   2  5  1
5   2  6  1
6   2  6  1
7   3  7  1
8   3  7  1
9   4  6  1
10  4  7  1
11  4  7  1

Me gustaría tener otra columna para almacenar un valor de una suma de los valores de C para la renta fija (tanto) a y B. es decir, algo como:

    A  B  C  D
0   1  5  1  2
1   1  5  1  2
2   1  6  1  1
3   1  7  1  1
4   2  5  1  1
5   2  6  1  2
6   2  6  1  2
7   3  7  1  2
8   3  7  1  2
9   4  6  1  1
10  4  7  1  2
11  4  7  1  2

He probado con los pandas groupby y el tipo de obras:

res = {}
for a, group_by_A in df.groupby('A'):
    group_by_B = group_by_A.groupby('B', as_index = False)
    res[a] = group_by_B['C'].sum()

pero no sé cómo obtener los resultados de res en df en la ordenada. Sería muy feliz con algún consejo sobre esto. Gracias.

3 Comentarios

  1. 17

    Aquí es una manera (aunque no se siente esto debería funcionar en uno ir con un aplique, yo no puedo conseguirlo).

    In [11]: g = df.groupby(['A', 'B'])
    
    In [12]: df1 = df.set_index(['A', 'B'])

    La tamaño groupby función es la que usted desea, tenemos que coincidir con la ‘a’ y ‘B’ como el índice:

    In [13]: df1['D'] = g.size()  # unfortunately this doesn't play nice with as_index=False
    # Same would work with g['C'].sum()
    
    In [14]: df1.reset_index()
    Out[14]:
        A  B  C  D
    0   1  5  1  2
    1   1  5  1  2
    2   1  6  1  1
    3   1  7  1  1
    4   2  5  1  1
    5   2  6  1  2
    6   2  6  1  2
    7   3  7  1  2
    8   3  7  1  2
    9   4  6  1  1
    10  4  7  1  2
    11  4  7  1  2
    • Gracias @Andy Hayden! La solución con sum es más genérico, creo. De hecho, no tengo 1‘s en C (cuando size funciona a la perfección, como usted ha señalado en su solución), sino más bien algunas carrozas, así que para que funcione correctamente tengo que ir con sum. Pero de todos modos, genial, gracias de nuevo.
    • Creo que el one-liner soñabas es df['D'] = df.groupby(['A', 'B']).transform(np.size). En tiempos buenos y malos, transform está ahí. 😀
  2. 9

    También podrías hacer un forro con transformar aplicado a la groupby:

    df['D'] = df.groupby(['A','B'])['C'].transform('sum')
  3. 8

    También podrías hacer un forro con mezcla de la siguiente manera:

    df = df.merge(pd.DataFrame({'D':df.groupby(['A', 'B'])['C'].size()}), left_on=['A', 'B'], right_index=True)
    • fácil de leer y entender

Dejar respuesta

Please enter your comment!
Please enter your name here