2014-06-19 20 views
1

似乎應該有一個numpy函數來查找兩個向量的重疊,但我似乎無法找到它。也許你們中的一個知道它?Numpy函數來查找重疊向量的索引

這個問題最好用一個簡單的代碼來描述(下面)。我有兩組數據(x1,y1)和(x2,y2),其中每個x和y是數百個元素。我需要將它們全部截斷以使域相同(即x1 = x2),並且y1表示與新x1一起使用的適當範圍,y2也將被截斷以與新x2一起移動。

# x1 and y1 are abscissa and ordinate from some measurement. 
x1 = array([1,2,3,4,5,6,7,8,9,10]) 
y1 = x1**2 # I'm just making some numbers for the ordinate. 

# x2 and y2 are abscissa and ordinate from a different measurement, 
# but not over the same exact range. 
x2 = array([5,6,7,8,9,10,11,12,13]) 
y2 = sqrt(x2) # And some more numbers that aren't the same. 

# And I need to do some math on just the portion where the two measurements overlap. 
x3 = array([5,6,7,8,9,10]) 
y3 = y1[4:10] + y2[:6] 

# Is there a simple function that would give me these indices, 
# or do I have to do loops and compare values? 
print x1[4:10] 
print x2[:6] 


# ------------ THE FOLLOWING IS WHAT I WANT TO REPLACE ------------- 


# Doing loops is really clumsy... 

# Check which vector starts lower. 
if x1[0] <= x2[0]: 
    # Loop through it until you find an index that matches the start of the other. 
    for i in range(len(x1)): 
     # Here is is. 
     if x1[i] == x2[0]: 
      # Note the offsets for the new starts of both vectors. 
      x1off = i 
      x2off = 0 
      break 
else: 
    for i in range(len(x2)): 
     if x2[i] == x1[0]: 
      x1off = 0 
      x2off = i 
      break 

# Cutoff the beginnings of the vectors as appropriate. 
x1 = x1[x1off:] 
y1 = y1[x1off:] 
x2 = x2[x2off:] 
y2 = y2[x2off:] 

# Now make the lengths of the vectors be the same. 
# See which is longer. 
if len(x1) > len(x2): 
    # Cut off the longer one to be the same length as the shorter. 
    x1 = x1[:len(x2)] 
    y1 = y1[:len(x2)] 
elif len(x2) > len(x1): 
    x2 = x2[:len(x1)] 
    y2 = y2[:len(x1)] 

# OK, now the domains and ranges for the two (x,y) sets are identical.  
print x1, y1 
print x2, y2 

謝謝!

+0

'numpy.in1d(X1,X2)'?我不知道你的問題或這些事情如何重疊?但是這段代碼會給你'[5,6,7,8,9,10]' –

+0

它給了我一個True和False的向量。然後我必須通過第一個向量來找到第一個真實值,並將其設置爲我的偏移量,然後在第二個向量中找到相同的位置。 – ZSG

+1

err看到答案(這可能是一個更好的解決方案)...我想這將是'x1 [numpy.in1d(x1,x2)]' –

回答

3

對於一個簡單的路口,你可以使用np.intersect1d

In [20]: x1 = array([1,2,3,4,5,6,7,8,9,10]) 

In [21]: x2 = array([5,6,7,8,9,10,11,12,13]) 

In [22]: x3 = np.intersect1d(x1, x2) 

In [23]: x3 
Out[23]: array([ 5, 6, 7, 8, 9, 10]) 

但它看起來像你需要的東西不同。作爲@JoranBeasley在評論所說,你可以使用np.in1d,但你需要兩次使用它:

這裏的數據:

In [57]: x1 
Out[57]: array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) 

In [58]: y1 
Out[58]: array([ 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]) 

In [59]: x2 
Out[59]: array([ 5, 6, 7, 8, 9, 10, 11, 12, 13]) 

In [60]: y2 
Out[60]: 
array([ 2.23606798, 2.44948974, 2.64575131, 2.82842712, 3.  , 
     3.16227766, 3.31662479, 3.46410162, 3.60555128]) 

獲取(X1,Y1)的子集數據:

In [61]: mask1 = np.in1d(x1, x2) 

In [62]: xx1 = x1[mask1] 

In [63]: yy1 = y1[mask1] 

In [64]: xx1, yy1 
Out[64]: (array([ 5, 6, 7, 8, 9, 10]), array([ 25, 36, 49, 64, 81, 100])) 

獲取(x2,y2)數據的子集。注意的參數np.in1d順序現在x2, x1是:

In [65]: mask2 = np.in1d(x2, x1) 

In [66]: xx2 = x2[mask2] 

In [67]: yy2 = y2[mask2] 

In [68]: xx2, yy2 
Out[68]: 
(array([ 5, 6, 7, 8, 9, 10]), 
array([ 2.23606798, 2.44948974, 2.64575131, 2.82842712, 3.  , 
     3.16227766])) 

我們真的沒有形成xx2,因爲這將是一樣xx1。我們現在可以在yy1yy2上運行。例如: -

In [69]: yy1 + yy2 
Out[69]: 
array([ 27.23606798, 38.44948974, 51.64575131, 66.82842712, 
     84.  , 103.16227766]) 
+0

不完全。它將兩個x向量的範圍設置爲相同,但對於與它一起使用的y向量,它不會給出相同的結果。我已經在問題中添加了循環以使其更加明確。 – ZSG

+0

太棒了!謝謝! – ZSG