在Python中查找数组中突然变化的开始和结束



对Python非常陌生,根据我的学习,这个任务似乎无法解决。

请帮助:

  1. 我有一个由Python程序创建的数组,它提供了一个像这样的1d数组:

    [0,0,.01,.1,1,1,.1,.01,0,0,0,0.01,.1,1,.1,.01,0,0,0,.01,.1,1,1,.1,.01,0,0,0,.01,.1,1,1]

  2. 你可以看到数组数从0到最大值,然后又多次变为0。

  3. 我需要找到它每次开始上升和下降的索引。这里是[3,9,12,17,20,26,29]

这是我到目前为止所尝试的,但是徒劳的

My_array==[0,0,.01,.1,1,1,.1,.01,0,0,0,0.01,.1,1,.1,.01,0,0,0,.01,.1,1,1,.1,.01,0,0,0,.01,.1,1,1]
def _edge(ii):
    for i in range (ii, len(My_array)):
        if np.abs(My_array[i]-My_array[i-1])>.01;
        index=i # save the index where the condition met
        break
    for ii in range (1, len(My_array))
    if ii <len(My_array): # make sure the loop continues till the end
        F1_Index=_edge(ii)
        F1_Index1.append(F1_Index)

如果您使用numpy,您可以这样做:

import numpy as np
a = np.array([0,0,.01,.1,1,1,.1,.01,0,0,0,0.01,.1,1,.1,.01,0,0,0,.01,.1,1,1,.1,.01,0,0,0,.01,.1,1,1])
b = a[1:] - a[:-1]  # find differences between sequential elements
v = abs(b) == 0.01  # find differences whose magnitude are 0.01
                    # This returns an array of True/False values
edges = v.nonzero()[0] # find indexes of True values
edges += 2  # add 1 because of the differencing scheme, 
            # add 1 because the results you give in the question 
            # are 1 based arrays and python uses zero based arrays
edges
>  array([ 3,  9, 12, 17, 20, 26, 29], dtype=int64)

这是我发现的做这类事情最快的方法。

我认为下面是你所需要的。它首先构建一个包含-1, 01的列表,给出相邻值之间的差异(不幸的是,cmp已从Python 3中删除,因为这是执行此操作的完美函数)。然后,它使用groupby函数和一个非零过滤器来生成方向改变时的索引列表:

import itertools
My_array = [0, 0, .01, .1, 1, 1, .1, .01, 0, 0, 0, 0.01, .1, 1, .1, .01, 0, 0, 0, .01, .1, 1, 1, .1, .01, 0, 0, 0, .01, .1, 1, 1]
def my_cmp(x,y):
    if x == y:      # Or for non-exact changes use:  if abs(x-y) <= 0.01:
        return 0
    else:
        return 1 if y > x else -1
def pairwise(iterable):
    a, b = itertools.tee(iterable)
    next(b, None)
    return zip(a, b)
slope = [(my_cmp(pair[1], pair[0]), index) for index, pair in enumerate(pairwise(My_array))]
indexes_of_changes = [next(g)[1]+1 for k,g in itertools.groupby(slope, lambda x: x[0]) if k != 0]
print(indexes_of_changes)

为您的数据提供以下结果:

[2, 6, 11, 14, 19, 23, 28]

注意,这给你任何方向的变化,而不仅仅是> 0.01

这是我的工作方式(主要是从Brad的代码中学到的)。仍然不太明白b.nonzero()[0]是如何工作的。Brad,如果可能的话,请解释一下。

import numpy as np
a = np.array([0,0,.01,.1,1,1,.1,.01,0,0,0,0.01,.1,1,.1,.01,0,0,0,.01,.1,1,1,.1,.01,0,0,0,.01,.1,1,1])
b0=[x>.1 for x in a] # making array of true and false
b0=np.array(b0) 
b0=b0*1# converting true false to 1 and 0
b=abs(b0[1:]-b0[:-1])# now I only have 1 where there is a change
edges = b.nonzero()[0] # find indexes of 1 values
edges

阵列((3、5、12、13、20、22、29],dtype = int64)

相关内容

最新更新