numpy确定参数之间的平均差异

时间:2014-07-04 17:27:21

标签: numpy scipy

是否有任何现成的函数来确定排序列表的参数之间的平均差异?

例如,这是我的手动尝试:

import numpy as np
rand_A = np.random.rand_integers(0, 99, 10)
np.sort(rand_A)
array([ 3,  8, 26, 34, 35, 37, 65, 82, 89, 94])

def mean_period(data):
    diffe = 0
    for ind in range(data.shape[0] - 1)
        diffe += data[ind + 1] - data[ind]
    return (diffe / (data.shape[0] - 1))

mean_period(np.sort(rand_A))
10

基本上我需要这个函数来确定类似于正弦信号的频率值,该信号将用作scipy.leastsq函数的初始猜测参数以适合它。 我需要最快的例程。我担心我的尝试将是一个很大的负担。

2 个答案:

答案 0 :(得分:3)

让我们看看。如果我理解你的问题,我们正在讨论频率检测器中的过零点。您有一个列表中的过零点的时间戳(然后根据需要进行排序),并希望计算列表中项目的平均差异。

虽然unutbu的答案是正确且非常Numpyish,但我想建议简要介绍一下数学。连续元素的平均差异是:

{ (s_1 - s_0) + (s_2 - s_1) + (s_3 - s_2) + ... + (s_n - s_(n-1)) } / n

似乎有很多条款取消了。剩下的是:

(s_n - s_0) / n

所以,上面的函数变为:

def mean_period(data):
    return 1. * (data[-1] - data[0]) / (len(data) - 1)

如果我们对排序数据做一些基准测试,那么:

rand_A = np.random.randint(0,99999999,10000000)
sort_A = np.sort(rand_A)

% timeit np.diff(sort_A).mean()     # 37.7 ms
% timeit mean_period(sort_A)        # 0.98 ms

(后者基本上是O(1)加上它会受到轻微的函数调用开销的影响。)

如果数据没有排序,那么我们必须找到最大和最小的值:

def mean_period_unsorted(data):
    smallest = np.min(data)
    largest = np.max(data)
    return 1. * (largest - smallest) / (len(data) - 1)

所以也许这次有点数学帮助:) 现在是基准

% timeit np.diff(np.sort(rand_A)).mean()   # 733 ms
% timeit mean_period_unsorted(rand_A)      # 17.9 ms

答案 1 :(得分:2)

np.diff(np.sort(rand_A)).mean()

几乎等同于mean_period(np.sort(rand_A)),但应该更快,因为它使用NumPy方法调用而不是Python循环。

我说"差不多等同于#34;因为存在一个区别:mean_period始终返回一个int,因为diffenumpy.int32,返回值是将此int32除以int的结果},(data.shape[0]-1)。

相反,np.diff(np.sort(rand_A)).mean()会返回Numpy float64


编辑:对于小数组(例如您在问题中发布的数组),Python循环更快:

In [84]: %timeit mean_period(np.sort(rand_A))
100000 loops, best of 3: 8.29 µs per loop

In [85]: %timeit np.diff(np.sort(rand_A)).mean()
10000 loops, best of 3: 21.5 µs per loop

但是对于大型数组,例如百万元素数组,

rand_A = np.random.random_integers(0, 99, 10**6)

使用NumPy的meandiff方法要快得多:

In [87]: %timeit mean_period(np.sort(rand_A))
1 loops, best of 3: 442 ms per loop

In [88]: %timeit np.diff(np.sort(rand_A)).mean()
10 loops, best of 3: 48.8 ms per loop

另见: