【问题标题】:Pandas: Solving for the threshold of highest values for a time-series datasetPandas:求解时间序列数据集的最大值阈值
【发布时间】:2016-07-01 08:52:46
【问题描述】:

给定:我有一组一天的时间序列数据,比如 96 个值。我有一个累积值,比如给定时间段内的 101 个单位。

问题:我需要找到阈值 X,其中高于该阈值的所有值的总和为给定的累积值 101。请参见下面的可视化图表:

  • X 值(黑线)是所需的阈值
  • 101(曲线下的红色区域)是给定的累计值
  • 蓝线是时间序列数据

约束:我必须多次执行此计算(一年中的每一天),因此最好避免迭代,但不是必需的。

样本数据:

DateTime    Usage_KWH
1/1/2015 0:15   10.32
1/1/2015 0:30   10.56
1/1/2015 0:45   9.84
1/1/2015 1:00   9.36
1/1/2015 1:15   10.32
1/1/2015 1:30   9.6
1/1/2015 1:45   9.6
1/1/2015 2:00   10.32
1/1/2015 2:15   9.84
1/1/2015 2:30   9.6
1/1/2015 2:45   10.08
1/1/2015 3:00   9.36
1/1/2015 3:15   9.84
1/1/2015 3:30   10.32
1/1/2015 3:45   9.84
1/1/2015 4:00   9.84
1/1/2015 4:15   10.08
1/1/2015 4:30   9.6
1/1/2015 4:45   9.6
1/1/2015 5:00   10.8
1/1/2015 5:15   9.6
1/1/2015 5:30   9.84
1/1/2015 5:45   14.76
1/1/2015 6:00   14.4
1/1/2015 6:15   14.76
1/1/2015 6:30   15.12
1/1/2015 6:45   14.4
1/1/2015 7:00   14.4
1/1/2015 7:15   14.04
1/1/2015 7:30   12.96
1/1/2015 7:45   14.04
1/1/2015 8:00   12.6
1/1/2015 8:15   12.96
1/1/2015 8:30   14.04
1/1/2015 8:45   12.96
1/1/2015 9:00   17.28
1/1/2015 9:15   17.28
1/1/2015 9:30   17.76
1/1/2015 9:45   17.28
1/1/2015 10:00  17.76
1/1/2015 10:15  16.8
1/1/2015 10:30  17.28
1/1/2015 10:45  19.68
1/1/2015 11:00  17.28
1/1/2015 11:15  16.8
1/1/2015 11:30  16.8
1/1/2015 11:45  17.28
1/1/2015 12:00  16.8
1/1/2015 12:15  17.28
1/1/2015 12:30  17.28
1/1/2015 12:45  16.8
1/1/2015 13:00  17.28
1/1/2015 13:15  16.8
1/1/2015 13:30  16.8
1/1/2015 13:45  17.28
1/1/2015 14:00  25.92
1/1/2015 14:15  25.2
1/1/2015 14:30  25.2
1/1/2015 14:45  25.2
1/1/2015 15:00  25.2
1/1/2015 15:15  25.92
1/1/2015 15:30  25.2
1/1/2015 15:45  25.92
1/1/2015 16:00  25.92
1/1/2015 16:15  23.76
1/1/2015 16:30  23.76
1/1/2015 16:45  23.76
1/1/2015 17:00  24.48
1/1/2015 17:15  25.92
1/1/2015 17:30  8.88
1/1/2015 17:45  9.12
1/1/2015 18:00  8.88
1/1/2015 18:15  9.6
1/1/2015 18:30  8.88
1/1/2015 18:45  9.12
1/1/2015 19:00  9.12
1/1/2015 19:15  9.6
1/1/2015 19:30  9.12
1/1/2015 19:45  8.88
1/1/2015 20:00  9.12
1/1/2015 20:15  9.36
1/1/2015 20:30  9.12
1/1/2015 20:45  8.88
1/1/2015 21:00  6
1/1/2015 21:15  6
1/1/2015 21:30  6
1/1/2015 21:45  4
1/1/2015 22:00  5
1/1/2015 22:15  6
1/1/2015 22:30  7
1/1/2015 22:45  5
1/1/2015 23:00  7
1/1/2015 23:15  4
1/1/2015 23:30  6
1/1/2015 23:45  5

我蹩脚的迭代代码:

time_series_df = pd.DataFrame(time_series_list)

#Iterative approach taking 10 steps
for x in (time_series_df.max, time_series_df.min, -(time_series_df.max)/10):
    #Getting values above an arbitrary threshold
    temp = time_series_df.query('Usage_KWH > @x')
    #If the difference above threshold and aggregate sum for the day are less than given cumulative value then try again
    if time_series_df.sum - temp < 101:
        final_threshold = temp
#print the highest value that did not exceed 101
print('final answer', final_threshold)

额外:我尝试过使用 clip_upper、rank、cumsum、quantile 和 nlargest 的变体。我正在使用熊猫 0.18

【问题讨论】:

    标签: algorithm pandas


    【解决方案1】:

    这里对数据进行排序的技巧.. 这是一种方法。速度可能会有所提高!

    df2           = df.sort_values(['Usage_KWH'], ascending=[False]).reset_index()
    df2['KWHcum'] = df2['Usage_KWH'].cumsum()/  (df2.index+1) 
    df2["dif"]    = np.round( df2['KWHcum'] - df2['Usage_KWH'], 3)*(df2.index+1)
    df2
    
    #        index DateTime  Usage_KWH     KWHcum       dif
    # 0   1/1/2015    14:00      25.92  25.920000    0.0000
    # 1   1/1/2015    16:00      25.92  25.920000    0.0000
    # 2   1/1/2015    15:45      25.92  25.920000    0.0000
    # 3   1/1/2015    15:15      25.92  25.920000    0.0000
    # 4   1/1/2015    17:15      25.92  25.920000    0.0000
    # 5   1/1/2015    14:45      25.20  25.800000    3.6000
    # 6   1/1/2015    14:15      25.20  25.714286    3.6001
    # 7   1/1/2015    15:30      25.20  25.650000    3.6000
    # 8   1/1/2015    14:30      25.20  25.600000    3.6000
    # 9   1/1/2015    15:00      25.20  25.560000    3.6000
    # 10  1/1/2015    17:00      24.48  25.461818   10.7998
    # 11  1/1/2015    16:30      23.76  25.320000   18.7200
    # 12  1/1/2015    16:45      23.76  25.200000   18.7200
    # 13  1/1/2015    16:15      23.76  25.097143   18.7194
    # 14  1/1/2015    10:45      19.68  24.736000   75.8400
    # 15  1/1/2015     9:30      17.76  24.300000  104.6400
    # 16  1/1/2015    10:00      17.76  23.915294  104.6401
    # 17  1/1/2015    11:00      17.28  23.546667  112.8006
    # 18  1/1/2015     9:45      17.28  23.216842  112.7992
    # 19  1/1/2015    12:30      17.28  22.920000  112.8000
    # 20  1/1/2015    10:30      17.28  22.651429  112.7994
    # 21  1/1/2015    12:15      17.28  22.407273  112.8006
    # 22  1/1/2015    13:00      17.28  22.184348  112.7989
    # 23  1/1/2015    11:45      17.28  21.980000  112.8000
    # 24  1/1/2015    13:45      17.28  21.792000  112.8000
    # 25  1/1/2015     9:00      17.28  21.618462  112.8010
    # 26  1/1/2015     9:15      17.28  21.457778  112.8006
    # 27  1/1/2015    11:15      16.80  21.291429  125.7592
    # 28  1/1/2015    11:30      16.80  21.136552  125.7614
    # 29  1/1/2015    10:15      16.80  20.992000  125.7600
    
     df2           = df2[df2['dif'] < 101]
     print df2['Usage_KWH'].tail(1)    
      #  14    19.68
      # Name: Usage_KWH, dtype: float64
    
    df2           = df2[df2['dif'] < 141]
    print df2['Usage_KWH'].tail(1)    
    #33    16.8
    #Name: Usage_KWH, dtype: float64
    

    【讨论】:

    • 感谢它运行良好。我添加了一些额外的代码,这些代码将 101 的剩余部分未应用并在各个步骤中取平均值
    【解决方案2】:

    我不知道 Pandas 是什么,但这里有一个解决方案。设n个数在数组y[]中,面积阈值(如101)为A:

    1. 按降序排列 y[]。 (请注意,出于选择阈值的目的,各个值的顺序无关紧要。)
    2. 设置跑步区域总t = 0。同时设置old_t = 0。
    3. 设置 i = 0。现在我们假设将阈值设置为 y[i];因为 i = 0 最初,这意味着我们最初将阈值设置为完全等于最高元素。随着 i 的增加,我们的暂定阈值 y[i] 会变低,我们的跑步区域总 t 会增加。
    4. 当 t
    5. i = i + 1
    6. old_t = t
    7. t = t + i * (y[i-1] - y[i])
  • 如果 t
  • 否则,如果 t = A 则报告 y[i] 作为阈值,然后停止。
  • 否则,它一定是 t > A,这意味着我们已经走得太低了——我们需要将阈值设置在 y[i-1] 和 y[i] 之间的某个位置:
    • 我们想要求解方程 A = old_t + i * (y[i-1] - x) 以获得所需的阈值水平 x。这意味着:
    • 报告 y[i-1] - (A - old_t) / i 作为阈值,然后停止。
  • 这个算法的运行时间主要取决于第一步对 y[] 进行排序所需的时间,即 O(n log n),因此即使是数百万的 n 也需要毫秒。

    【讨论】:

      猜你喜欢
      • 2021-04-27
      • 2023-02-25
      • 1970-01-01
      • 2021-01-05
      • 2021-09-23
      • 2019-07-04
      • 2020-02-12
      • 1970-01-01
      • 2021-03-13
      相关资源
      最近更新 更多