使用NumPy加速数组间隔比较

时间:2014-05-08 14:32:28

标签: python arrays numpy

我在一定的时间间隔内有大量的数据点,我试图通过查看这两个时间间隔之间的重叠来计算不同时间间隔内该数据的加权平均值。我有一个成功的方法,如下所述,但它很慢。我正在寻找关于如何让这种运行更快的建议。

我有两组时间间隔以及与其中一个时间间隔相关的数据点。我需要确定第一个时间间隔中的哪个数据点落入第二个时间间隔。例如,如果以下是我的数组:

start1 = np.array([1.,6.,11.,16.,21.,26.,31.,36.])
stop1 = np.array([6.,11.,16.,21.,26,31.,36.,41.])
start2 = np.array([1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,...,39.])
stop2 = np.array([2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,...,40.])
data1 = np.array([2.,4.,3.,8.,4.,7.,2.,6.])

然后我的结果将是:

[array([ 2.]), array([ 2.]), array([ 2.]), array([ 2.]), array([ 2.,  4.]), array([ 2.,  4.]), array([ 4.]), array([ 4.]), array([ 4.]), array([ 4.,  3.]), array([ 4.,  3.]), array([ 3.]), array([ 3.]), array([ 3.]), array([ 3.,  8.]), array([ 3.,  8.]), array([ 8.]), array([ 8.]), array([ 8.]), array([ 8.,  4.]), array([ 8.,  4.]), array([ 4.]), array([ 4.]), array([ 4.]), array([ 4.,  7.]), array([ 4.,  7.]), array([ 7.]), array([ 7.]), array([ 7.]), array([ 7.,  2.]), array([ 7.,  2.]), array([ 2.]), array([ 2.]), array([ 2.]), array([ 2.,  6.]), array([ 2.,  6.]), array([ 6.]), array([ 6.]), array([ 6.])]

这是我目前正在使用的方法:

intervals_data = []
for i in range(0, len(start2)):
    intervals_data.append(data1[((stop1>=start2[i]) & (start1<=stop2[i]))])

我遇到的问题是这些数组通常大约为25,000个元素,因此每个数据集大约需要20秒。我通常有几百个数据集,所以最终需要大约一个小时才能运行。

有人可以指点我更快的方法吗?谢谢!

2 个答案:

答案 0 :(得分:2)

我们的想法是使用二进制搜索为i中的每个条目start2[j]找到最左侧索引stop1,以便插入将stop1排序,即, start2[j] <= stop1[i]。同样,我们正在为i中的每个stop2[j]寻找最合适的start1,即stop2[j] >= stop1[i]。这可以通过以下方式实现:

start_indx = stop1.searchsorted(start2, "left")
end_indx = start1.searchsorted(stop2, "right")
result = [data1[start_indx[i]:end_indx[i]]for i in range(len(start_indx))]

答案 1 :(得分:0)

您可以尝试基于迭代器的方法:

inter1 = zip(start1, stop1, data1)
inter2 = zip(start2, stop2)
data2 = []

curr1 = next(inter1)

for curr2 in inter2:
  vals = []
  while curr2[0] > curr1[1]:
    curr1 = next(inter1)
  vals.append(curr1[2])
  while curr2[1] > curr1[1]:
    curr1 = next(inter1)
    vals.append(curr1[2])
  data2.append(np.array(vals))

return data2

这里的要点是你应该只沿着间隔前进前进,所以迭代器应该完成工作。

PD:我在这里假设Python 3.x.如果您使用的是Python 2.x,只需将zip替换为izip