熊猫在滚动时间窗口中找到最大值

时间:2016-03-29 10:29:13

标签: python pandas

我有一个表df,其中包含"timestamp"列和"Y"列。我想添加另一列"MaxY",其中包含最多24小时后最大的Y值。那是

df.MaxY.iloc[i] = df[(df.timestamp > df.timestamp.iloc[i]) &
                     (df.timestamp < df.timestamp.iloc[i] + timedelta(hours=24))].Y.max()

显然,像那样计算它是非常慢的。还有更好的方法吗?

在计算"SumY"的类似情况下,我可以使用cumsum()的技巧来完成。然而,类似的伎俩似乎不起作用。

根据要求,示例表(MaxY是输出。输入是前两列)。

-------------------------------
| timestamp        | Y | MaxY |
-------------------------------
| 2016-03-29 12:00 | 1 |   3  |  rows 2 and 3 fall within 24 hours, so MaxY = max(2,3)
| 2016-03-29 13:00 | 2 |   4  |  rows 3 and 4 fall in the time interval, so MaxY = max(3, 4)
| 2016-03-30 11:00 | 3 |   4  |  rows 4, 5, 6 all fall in the interval so MaxY = max(4, 3, 2)
| 2016-03-30 12:30 | 4 |   3  |  max (3, 2)
| 2016-03-30 13:30 | 3 |   2  |  row 6 is the only row in the interval
| 2016-03-30 14:00 | 2 | nan? |  there are no rows in the time interval. Any value will do.
-------------------------------

3 个答案:

答案 0 :(得分:1)

以下是重新采样/滚动的方法。我使用pandas版本0.18.0和python 3.5得到了一个奇怪的警告。我不认为这是一个问题,但不确定为什么会产生它。

这假定索引是&#39;时间戳&#39;如果没有,则在df = df.set_index('timestamp')之后加上以下内容:

>>> df2 = df.resample('30min').sort_index(ascending=False).fillna(np.nan)
>>> df2 = df2.rolling(48,min_periods=1).max()
>>> df.join(df2,rsuffix='2')

                     Y   Y2
timestamp                  
2016-03-29 12:00:00  1  3.0
2016-03-29 13:00:00  2  4.0
2016-03-30 11:00:00  3  4.0
2016-03-30 12:30:00  4  4.0
2016-03-30 13:30:00  3  3.0
2016-03-30 14:00:00  2  2.0

在这个微小的数据帧上,它似乎快了两倍,但是你必须在更大的数据帧上测试它才能合理地了解相对速度。

希望这有点自我扩张。升序排序是必要的,因为滚动只允许向后或居中的窗口,据我所知。

答案 1 :(得分:0)

考虑一个可能运行得更快的apply()解决方案。函数返回每行的时间条件序列的最大值。

import pandas as pd
from datetime import timedelta

def daymax(row):         
    ser = df.Y[(df.timestamp > row) &
               (df.timestamp <= row + timedelta(hours=24))]
    return ser.max()

df['MaxY'] = df.timestamp.apply(daymax)

print(df)

#            timestamp  Y  MaxY
#0 2016-03-29 12:00:00  1   3.0
#1 2016-03-29 13:00:00  2   4.0
#2 2016-03-30 11:00:00  3   4.0
#3 2016-03-30 12:30:00  4   3.0
#4 2016-03-30 13:30:00  3   2.0
#5 2016-03-30 14:00:00  2   NaN

答案 2 :(得分:0)

怎么了

df['MaxY'] = df[::-1].Y.shift(-1).rolling('24H').max()

df[::-1]反转df(您希望它“向后”),而shift(-1)则照顾“将来”。