【问题标题】:Detect significant changes in a data-set that gradually changes检测逐渐变化的数据集中的显着变化
【发布时间】:2017-09-29 01:47:33
【问题描述】:

我在 python 中有一个数据列表,表示每分钟使用的资源量。我想找出它在该数据集中发生显着变化的次数。我所说的重大变化与我目前所读到的有点不同。

例如如果我有一个像 [10,15,17,20,30,40,50,70,80,60,40,20]

我说当数据相对于之前的正常值增加一倍或减少一半时,就会发生重大变化。

例如由于列表以 10 开头,这是我们的起始正常点

然后当数据翻倍到 20 时,我将其视为一个重大变化并将正常设置为 20。

然后当数据翻倍到 40 时,就被认为是显着变化,现在正常是 40

那么当数据翻倍到80时,就认为是显着变化,现在正常是80

之后当数据减半到40时,视为又一次显着变化,正常变为40

最后当数据减半到20时,就是最后一次显着变化

这里总共有 5 个重大变化。

它是否类似于任何其他更改检测算法?如何在 python 中有效地做到这一点?

【问题讨论】:

    标签: python statistics data-analysis


    【解决方案1】:

    我对 Python 部分无能为力,但就数学而言,您提出的问题使用 log base 2 解决起来相当简单。当可以达到当前值除以常数时,就会发生重大变化通过将 2 提高到与前一个值不同的幂(作为整数)。 (需要该常量,因为数组中的第一个值构成了比较的基础。)

    对于t 处的每个元素,计算:

    current  = math.log(Array[t]  /Array[0], 2)
    previous = math.log(Array[t-1]/Array[0], 2)
    if math.floor(current) <> math.floor(previous) a significant change has occurred
    

    使用这种方法,您根本不需要跟踪“正常点”,您只需要数组。通过删除额外的状态变量,我们可以以任何顺序处理数组,如果数据集非常大,我们可以将数组的一部分分配给不同的线程。用你目前的方法是做不到的。

    【讨论】:

      【解决方案2】:

      这相对简单。您可以通过列表进行一次迭代来完成此操作。我们只是在发生“重大”变化时更新我们的基础。

      请注意,我的实现适用于任何可迭代对象或容器。例如,如果您想读取一个文件而不必将其全部加载到内存中,这将非常有用。

      def gen_significant_changes(iterable, *, tol = 2):
          iterable = iter(iterable) # this is necessary if it is container rather than generator.
          # note that if the iterable is already a generator iter(iterable) returns itself.
          base = next(iterable)
          for x in iterable:
              if x >= (base * tol) or x <= (base/tol):
                  yield x
                  base = x
      
      my_list = [10,15,17,20,30,40,50,70,80,60,40,20]
      
      print(list(gen_significant_changes(my_list)))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-03-24
        • 1970-01-01
        • 1970-01-01
        • 2014-02-27
        • 2017-08-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多