Python 如何使用应用于每列的不同函数对数据帧重新采样?

Python 如何使用应用于每列的不同函数对数据帧重新采样?,python,numpy,time-series,pandas,Python,Numpy,Time Series,Pandas,我有一个温度和辐射的时间序列,在熊猫数据框中。按常规步骤,时间分辨率为1分钟 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),

我有一个温度和辐射的时间序列,在熊猫数据框中。按常规步骤,时间分辨率为1分钟

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
<class 'pandas.core.frame.DataFrame'>
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)
导入日期时间
作为pd进口熊猫
将numpy作为np导入
date_times=pd.date_范围(datetime.datetime(2012,4,5,8,0)),
datetime.datetime(2012,4,5,12,0),
频率(1分钟)
tamb=np.随机样本(日期×大小)*10.0
辐射=np.随机样品(日期×尺寸)*10.0
frame=pd.DataFrame(数据={'tamb':tamb,'radiation':radiation},
索引=日期(单位时间)
框架
DatetimeIndex:241条记录,2012-04-05 08:00:00至2012-04-05 12:00:00
频率:T
数据列:
辐射241非空值
tamb 241非空值
数据类型:float64(2)

如何将此
数据帧的采样分辨率降低到一小时,计算温度的每小时平均值,以及辐射的每小时总和

您需要使用
groupby
如下:

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

        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
所以本质上我是在小时值上进行分割,然后计算
tamb
的平均值和
辐射的总和,然后返回
数据帧
(类似于R的
ddply
)。有关更多信息,我会查看文档页面以及博客文章

编辑:要使此比例更好,您可以按日期和时间分组:

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

您还可以使用的
asof
方法进行下采样


为了吸引您,在pandas 0.8.0中(在GitHub上的
timeseries
分支中进行了大量开发),您将能够:

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

上述方法是熊猫当前生产版本的正确策略。

对于熊猫0.18,重采样API已更改(请参阅)。 因此,对于熊猫>=0.18,答案是:

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
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

旧答案:

我回答我的问题是为了反映
pandas>=0.8
中与时间序列相关的变化(所有其他答案都已过时)

使用熊猫>=0.8,答案是:

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
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

谢谢,但我想要的是类似于
frame.convert('1h',how={'radiation':'sum',tamb':'mean'})的东西
。这是0.8中的一个选项吗?@Wes McKinney这应该是0.8中的
重采样,不是吗?如果你愿意更新你的答案,我会接受。否则,我认为您应该删除它,因为它会将用户指向错误的方向。这可以扩展到每列的函数列表:
frame.resample('1H',how={'radiance':[np.sum,np.min],'tamb':np.mean})
。生成的DataFrame在其列上有一个多索引,原始列名为0级,函数名为1级。要添加到我以前的注释中:您也可以使用字典,而不是每列的函数列表,其中键是新列名,值是要使用的函数:
frame.resample('1H',how={'radiation':{'sum_rad':np.sum,'min_rad':np.min},'tamb':np.mean})
说是否要在结果中添加新列,例如count()“@codingknob:对不起,我不理解你的评论。@bmu,如果我想用一个组合两列数据的自定义函数进行聚合,该怎么办?例如,如果我想用np.mean(frame['radiance']*frame['tamb'])进行聚合,该怎么办?