2015-11-15 28 views
3

假設我有在Python兩個列表:檢測1d列表值的交叉最簡單的方法是什麼?

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,並且跨過x = 6。

我想要做的是,有一個簡單的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 
+0

可以改變'如果LEN(np.unique(AA BB))== 1:''中(A> B)。 any()和(b> a).any()'這是更快的。 –

回答

1

首先做出兩條線的區別。

difference=a-b 

然後,如果差異的符號從一個項目改變到下一個(它將爲空)。你可以把它像:

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

[1:]是丟棄第一點,這是不相關的。交叉是True如果 剛纔有交集。

一個完整爲例:

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') 

有每個段交叉本身時間紅色菱形。在這種方法中,觸摸被認爲是雙重接觸。

crossing lines

+0

我喜歡它。實施:) –

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 
相關問題