Pandas - Resample / GroupBy DateTime Index并执行计算

时间:2018-05-09 05:28:58

标签: python pandas datetime time-series

我会尽力解释我需要帮助的内容。我有以下df(数千甚至数百万行),其日期时间索引如下例所示:

INDEX                   COL A       COL B
2018-05-07 21:53:13.731 0.365127    9391.800000
2018-05-07 21:53:16.201 0.666127    9391.800000
2018-05-07 21:53:18.038 0.143104    9391.800000
2018-05-07 21:53:18.243 0.025643    9391.800000
2018-05-07 21:53:18.265 0.640484    9391.800000
2018-05-07 21:53:18.906 -0.100000   9391.793421
2018-05-07 21:53:19.829 0.559516    9391.800000
2018-05-07 21:53:19.846 0.100000    9391.800000
2018-05-07 21:53:19.870 0.006560    9391.800000
2018-05-07 21:53:20.734 0.666076    9391.800000
2018-05-07 21:53:20.775 0.666076    9391.800000
2018-05-07 21:53:28.607 0.100000    9391.800000
2018-05-07 21:53:28.610 0.041991    9391.800000
2018-05-07 21:53:29.283 -0.053518   9391.793421
2018-05-07 21:53:47.322 -0.046302   9391.793421
2018-05-07 21:53:49.182 0.100000    9391.800000

我想做的是以5秒的间隔对行进行分组,并对每5秒间隔/子集执行(有时是复杂的)计算。

让我们举例说,我想计算每5秒钟内A列中正负值的百分比。

2018-05-07 21:53:102018-05-07 21:53:15仅包含一行,而A列为正数,因此我将使用100%创建新的C列。

同样地,2018-05-07 21:53:152018-05-07 21:53:20在A列中有8行,其中7行为正,其中1行为负。因此,列C将是87.5%

我会发布示例代码,但我真的不确定最好的方法。示例输出(新df)可能类似于下面的内容,COL D只是COL B中5秒分组的最小数字:

INDEX               COL C     COL D (MIN)
2018-05-07 21:53:10 100%     9391.800000
2018-05-07 21:53:15 12.5%    9391.793421
2018-05-07 21:53:20 100%     9391.800000
2018-05-07 21:53:25 66.7%    9391.793421
2018-05-07 21:53:30 nan      nan
2018-05-07 21:53:35 nan      nan
2018-05-07 21:53:40 nan      nan
2018-05-07 21:53:45 100%     9391.793421

请注意,我希望对每个分组进行许多不同的计算。因此,使用内置.sum().mean().agg()等不会足以进行更复杂的计算。

感谢任何帮助,如果需要,我很乐意澄清问题。

1 个答案:

答案 0 :(得分:3)

我认为需要正值的百分比需要值>0的平均值:

df = df.resample('5S').agg({'COL A': lambda x: (x > 0).mean() * 100, 'COL B': 'min'})
print (df)
                          COL A        COL B
INDEX                                       
2018-05-07 21:53:10  100.000000  9391.800000
2018-05-07 21:53:15   87.500000  9391.793421
2018-05-07 21:53:20  100.000000  9391.800000
2018-05-07 21:53:25   66.666667  9391.793421
2018-05-07 21:53:30         NaN          NaN
2018-05-07 21:53:35         NaN          NaN
2018-05-07 21:53:40         NaN          NaN
2018-05-07 21:53:45   50.000000  9391.793421

并且负值的百分比需要<0的平均值:

df = df.resample('5S').agg({'COL A': lambda x: (x < 0).mean() * 100, 'COL B': 'min'})
print (df)
                         COL A        COL B
INDEX                                      
2018-05-07 21:53:10   0.000000  9391.800000
2018-05-07 21:53:15  12.500000  9391.793421
2018-05-07 21:53:20   0.000000  9391.800000
2018-05-07 21:53:25  33.333333  9391.793421
2018-05-07 21:53:30        NaN          NaN
2018-05-07 21:53:35        NaN          NaN
2018-05-07 21:53:40        NaN          NaN
2018-05-07 21:53:45  50.000000  9391.793421

@Alexander指出0既不是积极的也不是消极的。所以最好是在计算之前删除它:

df = df.resample('5S').agg({'COL A': lambda x: (x[x.ne(0)] > 0).mean() * 100, 'COL B': 'min'})