Finding the point of intersection of 3 Numpy Arrays Python

流过昼夜 提交于 2021-02-11 04:36:56

问题


I am trying to code a function where it gives me the indexes of where either list_2 or list_3crosses list_. So it would give me the points of intersection if there are any in numpy code. 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. 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:

Expected 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

回答1:


The crossing points or intersection indices between two series a and b are the indices i where:

  • either (ai < bi and ai+1 > bi+1) (b crosses a from above)
  • or (ai > bi and ai+1 < bi+1) (b crosses a from below)
  • or ai = bi (a and b touch)

So we can get the indices by comparing the 'current' (i-th) and 'next' (i+1-th) values of each array.

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.

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'. 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]]

i.e. the first crossing is of b at index 7, then c at 9, then b at 13, and finally c at 15.




回答2:


This function converts arrays to lists and returns a list of tuples:

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


来源:https://stackoverflow.com/questions/65925654/finding-the-point-of-intersection-of-3-numpy-arrays-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!