Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 快速找到非零间隔_Python_Optimization_Numpy_Scipy_Signal Processing - Fatal编程技术网

Python 快速找到非零间隔

Python 快速找到非零间隔,python,optimization,numpy,scipy,signal-processing,Python,Optimization,Numpy,Scipy,Signal Processing,我正在写一个算法来确定密度图上“山脉”的间隔。如果有人感兴趣,该图是从Kinect的深处拍摄的。下面是这个算法发现的一个快速可视化示例:(移除小山): 我当前的算法: def find_peak_intervals(data): previous = 0 peak = False ranges = [] begin_range = 0 end_range = 0 for current in xrange(len(data)):

我正在写一个算法来确定密度图上“山脉”的间隔。如果有人感兴趣,该图是从Kinect的深处拍摄的。下面是这个算法发现的一个快速可视化示例:(移除小山):

我当前的算法:

def find_peak_intervals(data):
    previous = 0
    peak = False
    ranges = []
    begin_range = 0
    end_range = 0

    for current in xrange(len(data)):
        if (not peak) and ((data[current] - data[previous]) > 0):
            peak = True
            begin_range = current

        if peak and (data[current] == 0):
            peak = False
            end_range = current
            ranges.append((begin_range, end_range))

        previous = current

    return np.array(ranges)

这个功能可以正常工作,但在我的笔记本电脑上几乎需要3毫秒,我需要能够每秒至少运行30帧的整个程序。这个函数相当难看,我的程序每帧必须运行它3次,因此我想知道如何简化和优化这个函数的提示(可能是我错过的numpy或scipy中的一些内容)。

假设像这样的数据帧:

    Value
0       0
1       3
2       2
3       2
4       1
5       2
6       3
7       0
8       1
9       3
10      0
11      0
12      0
13      1
14      0
15      3
16      2
17      3
18      1
19      0
您可以使用
df[“Value”]获得连续的非零范围。shift(x)
其中
x
可以是
1
-1
,因此您可以检查它是否以零为界。一旦获得边界,就可以存储它们的索引对,并在以后过滤数据时使用它们

以下代码基于

结果如下:

1    3
2    2
3    2
4    1
5    2
6    3
Name: Value, dtype: int64
8    1
9    3
Name: Value, dtype: int64
13    1
Name: Value, dtype: int64
15    3
16    2
17    3
18    1
Name: Value, dtype: int64
在IPython中对其进行计时可得出以下结果:

%timeit find_peak_intervals(df)
1000 loops, best of 3: 1.49 ms per loop
这与您的速度尝试相差不远。另一种方法是使用将
pandas
系列转换为
numpy
阵列并从那里进行操作。让我们以@Warren Weckesser的这篇文章为例,对其进行修改以满足您的需要。我们也来计时吧

In [22]: np_arr = np.array(df["Value"])

In [23]: def greater_than_zero(a):
    ...:     isntzero = np.concatenate(([0], np.greater(a, 0).view(np.int8), [0]))
    ...:     absdiff = np.abs(np.diff(isntzero))
    ...:     ranges = np.where(absdiff == 1)[0].reshape(-1, 2)
    ...:     return ranges

In [24]: %timeit greater_than_zero(np_arr)
100000 loops, best of 3: 17.1 µs per loop
在17.1微秒时还不错,它也给出了相同的范围

[1 7] # Basically same as indices 1-6 in pandas.
[ 8 10] # 8, 9
[13 14] # 13, 13
[15 19] # 15, 18

看起来这个算法主要是一个寻零器。一旦找到一个非零元素,它就会停止比较连续的元素,并再次查找零。因此更像是“if peak and(data[current]==0:”后跟“elif(not peak)and(data[current]!=0:”?谢谢!这两种方法都非常有效。我的数据已经是numpy格式,所以你的第二种方法非常适合。时间从我的系统上的3毫秒(我知道我有一个potatoe)减少到了.21毫秒。
[1 7] # Basically same as indices 1-6 in pandas.
[ 8 10] # 8, 9
[13 14] # 13, 13
[15 19] # 15, 18