¿Cómo remuestrear un dataframe con diferentes funciones aplicadas a cada columna?

Tengo una serie de tiempos con temperatura y radiación en un dataframe pandas. La resolución del tiempo es de 1 minuto en pasos regulares.

 import datetime import pandas as pd import numpy as np date_times = pd.date_range(datetime.datetime(2012, 4, 5, 8, 0), datetime.datetime(2012, 4, 5, 12, 0), freq='1min') tamb = np.random.sample(date_times.size) * 10.0 radiation = np.random.sample(date_times.size) * 10.0 frame = pd.DataFrame(data={'tamb': tamb, 'radiation': radiation}, index=date_times) frame  DatetimeIndex: 241 entries, 2012-04-05 08:00:00 to 2012-04-05 12:00:00 Freq: T Data columns: radiation 241 non-null values tamb 241 non-null values dtypes: float64(2) 

¿Cómo puedo muestrear este dataframe de dataframe a una resolución de una hora, calculando la media horaria de la temperatura y la sum horaria de la radiación?

Con pandas 0.18, la API de remuestreo cambió (consulte la documentación ). Entonces para pandas> = 0.18 la respuesta es:

 In [31]: frame.resample('1H').agg({'radiation': np.sum, 'tamb': np.mean}) Out[31]: tamb radiation 2012-04-05 08:00:00 5.161235 279.507182 2012-04-05 09:00:00 4.968145 290.941073 2012-04-05 10:00:00 4.478531 317.678285 2012-04-05 11:00:00 4.706206 335.258633 2012-04-05 12:00:00 2.457873 8.655838 

Respuesta anterior:

Estoy respondiendo mi pregunta para reflejar los cambios relacionados con las series temporales en pandas >= 0.8 (todas las demás respuestas están desactualizadas).

Usando pandas> = 0.8 la respuesta es:

 In [30]: frame.resample('1H', how={'radiation': np.sum, 'tamb': np.mean}) Out[30]: tamb radiation 2012-04-05 08:00:00 5.161235 279.507182 2012-04-05 09:00:00 4.968145 290.941073 2012-04-05 10:00:00 4.478531 317.678285 2012-04-05 11:00:00 4.706206 335.258633 2012-04-05 12:00:00 2.457873 8.655838 

También puede asof la asof utilizando el método pandas.DateRange objetos pandas.DateRange .

 In [21]: hourly = pd.DateRange(datetime.datetime(2012, 4, 5, 8, 0), ... datetime.datetime(2012, 4, 5, 12, 0), ... offset=pd.datetools.Hour()) In [22]: frame.groupby(hourly.asof).size() Out[22]: key_0 2012-04-05 08:00:00 60 2012-04-05 09:00:00 60 2012-04-05 10:00:00 60 2012-04-05 11:00:00 60 2012-04-05 12:00:00 1 In [23]: frame.groupby(hourly.asof).agg({'radiation': np.sum, 'tamb': np.mean}) Out[23]: radiation tamb key_0 2012-04-05 08:00:00 271.54 4.491 2012-04-05 09:00:00 266.18 5.253 2012-04-05 10:00:00 292.35 4.959 2012-04-05 11:00:00 283.00 5.489 2012-04-05 12:00:00 0.5414 9.532 

Para atormentarlo, en pandas 0.8.0 (bajo un fuerte desarrollo en la twig de timeseries en GitHub), podrá hacer:

 In [5]: frame.convert('1h', how='mean') Out[5]: radiation tamb 2012-04-05 08:00:00 7.840989 8.446109 2012-04-05 09:00:00 4.898935 5.459221 2012-04-05 10:00:00 5.227741 4.660849 2012-04-05 11:00:00 4.689270 5.321398 2012-04-05 12:00:00 4.956994 5.093980 

Los métodos mencionados anteriormente son la estrategia correcta con la versión de producción actual de pandas.

Necesitas usar groupby como tal:

 grouped = frame.groupby(lambda x: x.hour) grouped.agg({'radiation': np.sum, 'tamb': np.mean}) # Same as: grouped.agg({'radiation': 'sum', 'tamb': 'mean'}) 

siendo la salida:

  radiation tamb key_0 8 298.581107 4.883806 9 311.176148 4.983705 10 315.531527 5.343057 11 288.013876 6.022002 12 5.527616 8.507670 

Así que, en esencia, estoy dividiendo el valor de la hora y luego calculando la media de tamb y la sum de la radiation y devolviendo el DataFrame (enfoque similar al ddply de R). Para más información, vería la página de documentación de groupby , así como esta publicación del blog.

Edición: para mejorar un poco esta escala, puede agrupar el día y la hora como tales:

 grouped = frame.groupby(lambda x: (x.day, x.hour)) grouped.agg({'radiation': 'sum', 'tamb': 'mean'}) radiation tamb key_0 (5, 8) 298.581107 4.883806 (5, 9) 311.176148 4.983705 (5, 10) 315.531527 5.343057 (5, 11) 288.013876 6.022002 (5, 12) 5.527616 8.507670