【问题标题】:Pandas finding max value in rolling window of time熊猫在滚动时间窗口中找到最大值
【发布时间】:2016-03-29 10:29:12
【问题描述】:

我有一张表df,列有"timestamp""Y"。我想添加另一列"MaxY",其中包含最大的Y 值,最多在未来24 小时内。那是

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

【问题讨论】:

  • 帮助我们为您提供帮助!请根据提供的样本提供一个包含 5-7 行的样本数据集和预期的输出/结果集。
  • @JohnE,据我了解,rolling() 仅适用于固定行数的窗口。我的是固定的时间间隔。
  • @MaxU,我希望简单代码的 sn-p 就足够了。现在我也添加了一张桌子。是不是更清楚了?
  • @JohnE,我也尝试使用rollingresample 来做这件事,但我做不到。你能给我们指路吗?谢谢!
  • @MaxU 好的,只是为了你,我试了一下。 ;-) 这比我想象的要棘手,但我认为工作正常。

标签: python pandas


【解决方案1】:

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

这假设索引是'timestamp',如果不是,在下面加上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

在这个很小的数据帧上,它的速度似乎大约是原来的两倍,但您必须在更大的数据帧上对其进行测试才能合理地了解相对速度。

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

【讨论】:

  • 谢谢你和++!我一直在玩 '1H' 频率并且总是有不好的结果 - 为什么它使用 '30min' 频率来做到这一点???
  • @MaxU 数据中有一些时间像 12:30 和 13:30,所以可能与 1 小时不完全相同?
  • 我现在看到了,谢谢你的解决和解释!
  • 嗯,这对真实数据来说不是很好。 resample() 的参数要么很小,因此会炸毁表格(特别是如果其中有任何时间间隔),或者它会很大,因此会产生错误的数字(也许我可以忍受)。
  • @KarolisJuodelė 你真的试过了吗?如果它在真实数据上没有更快,我会感到惊讶,因为你的方式基本上是 2*n^2 不等式测试,随着数据变大,它会越来越慢。这是一个公平的观点,你用 resample 和你的数据有多好,但我不确定是否可以做很多事情 - 尽管如果结果足够快,你可以让 resample 非常好。
【解决方案2】:

考虑一个运行速度更快的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

【讨论】:

    【解决方案3】:

    怎么了

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

    df[::-1] 反转 df(您希望它“向后”),shift(-1) 负责“未来”。

    【讨论】:

      猜你喜欢
      • 2020-03-26
      • 2019-10-21
      • 2017-03-30
      • 2022-11-16
      • 1970-01-01
      • 2017-08-27
      • 2016-09-10
      • 2020-04-21
      • 2021-03-30
      相关资源
      最近更新 更多