2013-02-25 29 views
4

這是初學者Numpy用戶的一個基本問題:我有一個說5行2列的二維數組,你可以看到10個2d向量,並且我想測試if一個給定的矢量在桌子裏面。測試給定數組的子陣列

例如:

>>> tableau = array(range(10), dtype = uint8) 
>>> tableau.shape = (5,2) 
>>> print tableau 
[[ 0 1] 
[ 2 3] 
[ 4 5] 
[ 6 7] 
[ 8 9]] 
>>> [0, 1] in tableau 
True 

最後一行給出真實的,但 '[0,2]在畫面' 太。

目前,我計算歐幾里德距離是否爲0,但我確定有一個更簡單的答案。

感謝所有幫助

+0

似乎是[此問題]的副本(http://stackoverflow.com/questions/7100242/python-numpy-first-occurrence-of-subarray)。 – Junuxx 2013-02-25 13:37:10

+0

@Junuxx這是一個不同的問題,這裏的矢量必須(顯然)匹配整行。 – 2013-02-25 13:47:21

+0

@Janne:你是怎麼想的?這個例子可能有一個向量,只要矩陣很寬,但問題清楚地說「我想測試一個給定的向量是否在表內」,這是更一般的。 – Junuxx 2013-02-25 13:48:56

回答

6

可以進行匹配陣列上的布爾減少:

([0, 1] == tableau).all(axis=1).any() 
+0

謝謝,它比我想象的更復雜:) – Fred 2013-02-25 13:44:49

+0

@Junuxx它爲我做;你在測試什麼? – ecatmur 2013-02-25 13:50:41

+0

@ecatmur:'[0,1]'。 – Junuxx 2013-02-25 13:52:51

0

我寫來解決這個,也負責處理多維情況下的功能。 (@ ecatmur的回答完全在兩個維度,但沒有一維或3D +)

import numpy as np 
def haselement(arr,subarr): 
    '''Test if subarr is equal to one of the elements of arr. 
     This is the equivalent of the "in" operator when using lists instead of arrays.''' 
    arr = np.asarray(arr) 
    subarr = np.asarray(subarr) 
    if subarr.shape!=arr.shape[1:]: 
     return False 
    elif arr.ndim<2: 
     return (subarr==arr).any() 
    else: 
     boolArr = (subarr==arr) 
     boolArr.resize([arr.shape[0],np.prod(arr.shape[1:])]) 
     return boolArr.all(axis=1).any() 

tableau = np.array(range(10), dtype = np.uint8) 
tableau.shape = (5,2) 
haselement(tableau,[0,1]) 

1D與if語句通過調整陣列2D使@ ecatmur處理,ND的處理算法會工作。我認爲解決這個問題的其他方法涉及列表理解或循環(實際上它可能更高效,但只有當列表很長且元素接近開始時)。儘管如此,這看起來更加樸實無華。

你也可以在這裏找到的功能,如果你寧願從庫中使用它:

https://github.com/davidmashburn/np_utils(明顯的免責聲明,我是作者;))

+0

順便說一句,haselement(arr,subarr)或elementof(subarr,arr)對人更有意義嗎?謝謝。 – David 2014-06-18 22:02:48

1

向前伸直,你可以使用any()來通過一個發生器比較陣列與array_equal

from numpy import array_equal 

in_t = lambda x, t : any((array_equal(a,x) for a in t)) 

print in_t([0, 2], tableau) 
print in_t([0, 1], tableau)