使用列表理解有效计算茶能峰度的最佳方法是什么?

What is the best way to efficiently compute the teager energy kurtosis using list comprehension?

我想在 Python 3.8 中的函数中计算 Teager Energy Kurtosis。我认为这也适用于列表理解。

我尝试使用以下代码,但收到一条错误消息,指出 numpy 对象不可迭代。变量 data 包含一个列表,其中包含加速度计的测量值。

def EO(data):
       numerator = pow(len(data),2)*sum((pow(((pow(data[i+1],2) - pow(data[i],2))-(sum(pow(data[i+1],2) - pow(data[i],2))/len(data))),4)) for i in range(len(data)-1))
       denominator = pow(sum(pow(((pow(data[i+1],2) - pow(data[i],2))-(sum(pow(data[i+1],2) - pow(data[i],2))/len(data))),2) for i in range(len(data)-1)),2)
       energy_operator = numerator/denominator
       return energy_operator

实现此类公式的一般方法是什么,您必须多次迭代,当然还要考虑效率。要计算值的数据集包含 133329 个条目。

我想主要问题是分母的和包含另一个必须先形成的和。怎么做 ?。如果没有列表理解,我会使用 for 循环遍历整个数据集两次,首先获得平均值,然后在第二次迭代中计算其余值。这样的可读性当然就没了。

欢迎提出任何建议!

干杯, 格瑞特

编辑: 这是不使用列表理解的工作代码:

def EO_5(data):
       summe = 0
       num_sum = 0
       den_sum = 0
       for i in range(1,len(data)-1):
          summe += pow(data[i],2)-((data[i-1])*(data[i+1]))
       ave = summe/len(data)
       for i in range(1,len(data)-1):
          num_sum += pow((pow(data[i],2)-((data[i-1])*(data[i+1])))-ave,4)
          den_sum += pow((pow(data[i],2)-((data[i-1])*(data[i+1])))-ave,2)
       numerator = (len(data)-1)*num_sum
       denominator = pow(den_sum,2)
       return numerator/denominator

在这里。

def EO_5(data):
  ave = (sum([i**2 for i in data[1:-1]])-sum([i*j for i,j in zip(data[:-2],data[2:])]))/len(data)
  num = (sum([(j**2-i*k-ave)**4 for i,j,k in zip(data[:-2],data[1:-1],data[2:])]))*(len(data)-1)
  den = (sum([(j**2-i*k-ave)**2 for i,j,k in zip(data[:-2],data[1:-1],data[2:])]))**2
  return num/den
sum(pow(data[i+1],2) - pow(data[i],2))

我认为这是 (a) 问题。 sum 的参数基本上只是一个数字,而它应该是类似列表(可迭代)的东西。

另一个问题是这是严重过度打高尔夫球。 运行 这么长的行被皱眉等

另一个问题是您共享的两个代码块中表达的数学似乎不匹配。第一个不起作用,似乎更接近您链接的图像中的内容,但如果这意味着它是“正确的”,则 IDK。你有没有更好的参考《Teager Energy Kurtosis》。

我没有以任何方式对此进行测试,但这几乎就是我简化您所说的有效代码的方式。

def EO_5(data):
    n = len(data) - 1)
    deltas = tuple(
        pow(x, 2) - (before * after)
        for (before, x, after)
        in zip(data[:-2], data[1:-1], data[2:])
    )
    ave = sum(deltas) / len(data)
    num_sum = sum(pow(d - ave, 4) for d in deltas)
    den_sum = sum(pow(d - ave, 2) for d in deltas)
    numerator = n * num_sum
    denominator = pow(den_sum, 2)
    return numerator / denominator

如果您在性能方面遇到问题,您可以使用 numpy 来利用矢量运算来使其更加精简,但我对此的经验有限。