是否有任何现成的函数来确定排序列表的参数之间的平均差异?
例如,这是我的手动尝试:
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函数的初始猜测参数以适合它。 我需要最快的例程。我担心我的尝试将是一个很大的负担。
答案 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,因为diffe
是numpy.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的mean
和diff
方法要快得多:
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
另见: