如何最简单地检测一维列表中的交叉值?

3
假设我在Python中有两个列表:
a = [1, 2, 3, 4, 5, 6] # y values of a line
b = [7, 6, 4, 4, 8, 4] # x values are index location of the list

// result = [F, F, F, T, F, T]

现在,如果您能想象这些点代表2条线,a和b。 线a只是按线性上升(尽管这是任意的),而线b下降并首先在x = 4处接触a,然后在x = 6处越过a。
我想做的是,有一个简单且Pythonic的解决方案来检测何时出现线交叉或相交。我想知道是否已经有numpy或其他库可以做到这一点。
编辑: 我编写了这个装置,我认为它可以检测交叉情况。aa <= bb; aa >= bb也应该使其检测到触摸。
# check if lines crossed in past X bars
def cross(a, b, bars=3):
    aa = np.array(a[-bars:])
    bb = np.array(b[-bars:])

    if len(np.unique(aa < bb)) == len(np.unique(aa > bb)) == 1:
        return False

    return True

你可以将 (if len(np.unique(aa < bb)) == len(np.unique(aa > bb)) == 1:) 替换为 (a>b).any() and (b>a).any(),后者更快。 - B. M.
2个回答

1

首先要区分这两行的不同之处。

difference=a-b

如果从一个项目到下一个项目的差异符号发生变化(在触摸时将为null),则存在交集。您可以这样实现:

cross=(np.sign(difference*np.roll(difference,1))<1)[1:]

[1:] 的作用是丢弃第一个不相关的点。如果有交叉点,则 crossTrue

完整示例:

import numpy as np
import matplotlib.pyplot as plt
a=np.random.randint(0,20,20)
b=np.random.randint(0,20,20)
plt.close()
plt.plot(a,'*-')
plt.plot(b,'*-')
difference=a-b
cross=(np.sign(difference*np.roll(difference,1))<1)[1:]
plt.plot(np.arange(.5,19),10* cross, 'd')

每当线段交叉时,会出现一个红色的菱形。在这种方法中,触点被视为双重接触。请保留HTML标签。

crossing lines


我喜欢它。已实现 :) - if __name__ is None

0
如果在相同的索引处,ab 的值相同,则两条线相交。如果 a 的前一个值高于 b 的前一个值,并且当前的 a 值低于当前的 b 值,则两条线是交叉的。使用 zip 同时迭代 ab,并使用变量 previous 存储先前的信息。
a = [1, 2, 3, 4, 5, 6] # y values of a line
b = [7, 6, 4, 4, 8, 4] # x values are index location of the list

previous = 0
result = []
for x, y in zip(a,b):
    if x == y: result.append(True) #touch
    else:
        comapre_result = 1 if x > y else -1
        if comapre_result + previous == 0:#cross-over
            result.append(True)
        else:
            result.append(False)
        previous = comapre_result

print result

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接