简体   繁体   English

找到 3 Numpy Arrays Python 的交点

[英]Finding the point of intersection of 3 Numpy Arrays Python

I am trying to code a function where it gives me the indexes of where either list_2 or list_3 crosses list_ .我正在尝试编写 function 代码,它为我提供list_2list_3与 list_ 交叉的list_ So it would give me the points of intersection if there are any in numpy code.因此,如果 numpy 代码中有任何交点,它将给我交点。 I want to get the crosses in order, so the list of indexes have to be formatted so that it would give me a cross in order of list_2 cross, list_3 cross, list_2 cross or list_3 cross, list_2 cross, list_3 cross etc. So if a cross has happened it has to wait for the other array values to cross the list before it can go through.我想按顺序获得十字架,因此必须对索引列表进行格式化,以便按照list_2 cross, list_3 cross, list_2 crosslist_3 cross, list_2 cross, list_3 cross等顺序给我一个十字架。所以如果发生了交叉,它必须等待其他数组值通过list才能通过 go。 I do not know how I can go through with this though I have tried using a numpy.where() function and such, I am also using the pandas module so if it has a valid function for this I could use that too. I do not know how I can go through with this though I have tried using a numpy.where() function and such, I am also using the pandas module so if it has a valid function for this I could use that too.

variables:变量:

list_ = np.array([9887.89 9902.99 9902.99 9910.23 9920.79 9911.34 9920.01 9927.51 9932.3
 9932.33 9928.87 9929.22 9929.22 9935.24 9935.24 9935.26 9935.26 9935.68
 9935.68 9940.5 ])
list_2 = np.array([9935.26 9935.26 9935.68 9935.68 9940.5  9925.19 9925.19 9929.62 9929.65
 9929.93 9932.55 9936.81 9936.84 9937.26 9932.55 9932.55 9932.55 9932.6
 9932.6  9932.6])
list_3_ = np.array([9928.87 9929.22 9929.22 9935.24 9935.24 9935.26 9935.26 9935.68 9935.68
 9940.5  9925.19 9925.19 9929.62 9929.65 9929.93 9932.55 9936.81 9936.84
 9937.26 9932.55])

plot: plot:

在此处输入图像描述

Expected Output:预期 Output:

List_2 cross at 5, List_3 cross at 10, List_2 cross at 14, List_3 cross at 15, List_2 cross at 18, List_3 cross at 19

The crossing points or intersection indices between two series a and b are the indices i where:两个系列ab之间的交叉点或交叉索引是索引i其中:

  • either (a i < b i and a i+1 > b i+1 ) ( b crosses a from above)要么 (a i < b i和 a i+1 > b i+1 ) ( b从上面穿过a )
  • or (a i > b i and a i+1 < b i+1 ) ( b crosses a from below)或 (a i > b i and a i+1 < b i+1 ) ( b从下方穿过a )
  • or a i = b i ( a and b touch)或 a i = b i ( ab接触)

So we can get the indices by comparing the 'current' ( i -th) and 'next' ( i+1 -th) values of each array.因此,我们可以通过比较每个数组的“当前”(第i个)和“下一个”(第i+1个)值来获得索引。

def intersection_points(a, *others):
    if a.ndim != 1 or any(other.shape != a.shape for other in others):
        raise ValueError('The arrays must be single dimensional and the same length')
    others = np.array(others)
    indices = np.argwhere(
            ((a[:-1] < others[..., :-1]) & (a[1:] > others[..., 1:])) |  
            ((a[:-1] > others[..., :-1]) & (a[1:] < others[..., 1:])) | 
            (a[:-1] == others[..., :-1]))
    return indices[indices[:, 1].argsort()]   # sort by i

a = np.array([9887.89, 9902.99, 9902.99, 9910.23, 9920.79, 9911.34, 9920.01, 9927.51, 9932.3, 9932.33, 9928.87, 9929.22, 9929.22, 9935.24, 9935.24, 9935.26, 9935.26, 9935.68, 9935.68, 9940.5])
b = np.array([9935.26, 9935.26, 9935.68, 9935.68, 9940.5, 9925.19, 9925.19, 9929.62, 9929.65, 9929.93, 9932.55, 9936.81, 9936.84, 9937.26, 9932.55, 9932.55, 9932.55, 9932.6, 9932.6, 9932.6])
c = np.array([9928.87, 9929.22, 9929.22, 9935.24, 9935.24, 9935.26, 9935.26, 9935.68, 9935.68, 9940.5, 9925.19, 9925.19, 9929.62, 9929.65, 9929.93, 9932.55, 9936.81, 9936.84, 9937.26, 9932.55])
print(intersection_points(a, b, c))

This returns an array of intersection points in this format:这将返回以下格式的交点数组:

[[ 0  7]
 [ 0  9]
 [ 1  9]
 [ 1 11]
 [ 1 12]
 [ 0 13]
 [ 1 15]
 [ 1 18]]

meaning that b (your list_2 ) intersects with a at indices 7, 9, 13, and c (your list_3 ) intersects with a at indices 9, 11, 12, 15 and 18.这意味着b (您的list_2 )在索引 7、9、13 处与a相交,并且c (您的list_3 )在索引 9、11、12、15 和 18 处与a相交。

You seem to want the returned value to somehow alternate between intersections of the different lines and 'wait for the other array values to cross the list before it can go through'.您似乎希望返回的值以某种方式在不同线的交点之间交替,并“等待其他数组值穿过列表,然后它才能通过 go”。 It's not entirely clear what this would mean in every case but you can possibly do this by manipulating the result like this:尚不完全清楚这在每种情况下意味着什么,但您可以通过像这样操作结果来做到这一点:

ip = intersection_points(a, b, c)
print(np.concatenate(([ip[0]], ip[1:][ip[:-1, 0] != ip[1:, 0]])))

returning返回

[[ 0,  7],
 [ 1,  9],
 [ 0, 13],
 [ 1, 15]]

ie the first crossing is of b at index 7, then c at 9, then b at 13, and finally c at 15.即第一个交叉点是索引 7 处的b ,然后是索引 9 处的c ,然后是 13 处的b ,最后是 15 处的c

This function converts arrays to lists and returns a list of tuples:此 function 将 arrays 转换为列表并返回元组列表:

def find_cross(list_, list_2, list_3):
    
    list_ = list_.tolist()
    list_2 = list_2.tolist()
    list_3 = list_3.tolist()
    
    cross = []
    i=0
    for x,y in zip(list_2, list_3):
        if x in list_:
            cross.append((i, list_.index(x)))
        if y in list_:
            cross.append((i, list_.index(y)))
        i+=1
    return cross

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM