2012-08-30 17 views
8

Tengo un 'RPT' indexado por (STK_ID, RPT_Date), contiene las ventas acumuladas de las acciones para cada qurter trama de datos:Cómo hacer un 'GroupBy' por el índice multinivel en pandas

     sales 
STK_ID RPT_Date 
000876 20060331  798627000 
     20060630  1656110000 
     20060930  2719700000 
     20061231  3573660000 
     20070331  878415000 
     20070630  2024660000 
     20070930  3352630000 
     20071231  4791770000 
600141 20060331  270912000 
     20060630  658981000 
     20060930  1010270000 
     20061231  1591500000 
     20070331  319602000 
     20070630  790670000 
     20070930  1250530000 
     20071231  1711240000 

quiero calcule las ventas de qurterly individuales usando 'groupby' por STK_ID & RPT_Yr, como: RPT.groupby('STK_ID','RPT_Yr')['sales'].transform(lambda x: x-x.shift(1)), ¿cómo hacer eso?

supongo que puedo obtener el año por lambda x : datetime.strptime(x, '%Y%m%d').year

Respuesta

8

Suponiendo aquí que RPT_Data es una cadena, ninguna razón por no usar de fecha y hora?

Es posible agrupar utilizando funciones, pero solo en un índice no MultiIndex. Para solucionar esto, restablezca el índice y configure 'RPT_Date' como índice para extraer el año (nota: pandas alterna entre objeto e int como dtype para 'RPT_Date').

In [135]: year = lambda x : datetime.strptime(str(x), '%Y%m%d').year 

In [136]: grouped = RPT.reset_index().set_index('RPT_Date').groupby(['STK_ID', year]) 

In [137]: for key, df in grouped: 
    .....:  print key 
    .....:  print df 
    .....: 
(876, 2006) 
      STK_ID  sales 
RPT_Date 
20060331  876 798627000 
20060630  876 1656110000 
20060930  876 2719700000 
20061231  876 3573660000 
(876, 2007) 
      STK_ID  sales 
RPT_Date 
20070331  876 878415000 
20070630  876 2024660000 
20070930  876 3352630000 
20071231  876 4791770000 
(600141, 2006) 
      STK_ID  sales 
RPT_Date 
20060331 600141 270912000 
20060630 600141 658981000 
20060930 600141 1010270000 
20061231 600141 1591500000 
(600141, 2007) 
      STK_ID  sales 
RPT_Date 
20070331 600141 319602000 
20070630 600141 790670000 
20070930 600141 1250530000 
20071231 600141 1711240000 

Otra opción es utilizar una columna tmp

In [153]: RPT_tmp = RPT.reset_index() 

In [154]: RPT_tmp['year'] = RPT_tmp['RPT_Date'].apply(year) 

In [155]: grouped = RPT_tmp.groupby(['STK_ID', 'year']) 

EDITAR La reorganización de su marco hacen que sea mucho más fácil.

In [48]: RPT 
Out[48]: 
            sales 
STK_ID RPT_Year RPT_Quarter    
876 2006  0    798627000 
       1   1656110000 
       2   2719700000 
       3   3573660000 
     2007  0    878415000 
       1   2024660000 
       2   3352630000 
       3   4791770000 
600141 2006  0    270912000 
       1    658981000 
       2   1010270000 
       3   1591500000 
     2007  0    319602000 
       1    790670000 
       2   1250530000 
       3   1711240000 

In [49]: RPT.groupby(level=['STK_ID', 'RPT_Year'])['sales'].apply(sale_per_q) 
Out[49]: 
STK_ID RPT_Year RPT_Quarter 
876  2006  0    798627000 
        1    857483000 
        2    1063590000 
        3    853960000 
     2007  0    878415000 
        1    1146245000 
        2    1327970000 
        3    1439140000 
600141 2006  0    270912000 
        1    388069000 
        2    351289000 
        3    581230000 
     2007  0    319602000 
        1    471068000 
        2    459860000 
        3    460710000 
+2

Es bastante complicado y el código es feo. ¿Hay alguna forma pitonica o pandasnic para hacerlo? – bigbug

+0

¿cuál es el código de 'sale_per_q'? – bigbug

+0

def sale_per_q (s): sq = s.diff() sq [s.index [0]] = s.iget (0) return sq –

0

Trate

RPT['sales'].groupby([RPT['STK_ID'],RPT['RPT_Yr']]).sum() 

^^ necesita hacer referencia a los índices dentro de una lista. esto funcionó para mí

Cuestiones relacionadas