2016-08-16 436 views
3

我試圖找到含有np.where一個子數組中的條目和狀況:查找包含numpy數組中子字符串的條目?

import numpy as np 
foo = "aa" 
bar = np.array(["aaa", "aab", "aca"]) 
np.where(foo in bar) 

這隻能返回一個空數組。
這是爲什麼?
是否有一個很好的替代解決方案?

回答

0

你試圖使用np.where的方式不正確。 np.where的第一個參數應該是一個布爾數組,並且您只是將它傳遞給一個布爾值。

foo in bar 
>>> False 
np.where(False) 
>>> (array([], dtype=int32),) 
np.where(np.array([True, True, False])) 
>>> (array([0, 1], dtype=int32),) 

的問題是,numpy的沒有定義in操作者作爲element-wise boolean operation

你可以完成你想要的一種方法是使用列表理解。

foo = 'aa' 
bar = np.array(['aaa', 'aab', 'aca']) 
out = [i for i, v in enumerate(bar) if foo in v] 
# out = [0, 1] 

bar = ['aca', 'bba', 'baa', 'aaf', 'ccc'] 
out = [i for i, v in enumerate(bar) if foo in v] 
# out = [2, 3] 
5

我們可以用np.core.defchararray.find找到foo字符串中的每一個bar元素,將返回-1如果沒有找到位置。因此,通過在find的輸出上檢查-1,它可用於檢測foo是否存在於每個元素中。最後,我們將使用np.flatnonzero來獲得匹配的索引。因此,我們將有一個實現,像這樣 -

np.flatnonzero(np.core.defchararray.find(bar,foo)!=-1) 

採樣運行 -

In [91]: bar 
Out[91]: 
array(['aaa', 'aab', 'aca'], 
     dtype='|S3') 

In [92]: foo 
Out[92]: 'aa' 

In [93]: np.flatnonzero(np.core.defchararray.find(bar,foo)!=-1) 
Out[93]: array([0, 1]) 

In [94]: bar[2] = 'jaa' 

In [95]: np.flatnonzero(np.core.defchararray.find(bar,foo)!=-1) 
Out[95]: array([0, 1, 2]) 
+0

這工作完美。非常感謝你!但出於好奇,你知道爲什麼np.where中的條件不起作用嗎? – SiOx

+0

@SiOx AFAIK作爲NumPy數組的'foo'不能在'in'中使用。那'in'是否適用於Python列表等,如果這有意義的話? – Divakar

+0

'in'確實可以處理數組,也就是'ndarray'有一個'__contains__'方法。但行爲與列表類似。 – hpaulj

0

看看使用in的一些例子:

In [19]: bar = np.array(["aaa", "aab", "aca"]) 

In [20]: 'aa' in bar 
Out[20]: False 

In [21]: 'aaa' in bar 
Out[21]: True 

In [22]: 'aab' in bar 
Out[22]: True 

In [23]: 'aab' in list(bar) 

它看起來像in與數組一起使用時,彷彿陣列的列表。 ndarray確實有__contains__方法,所以in的作品,但它可能很簡單。

但是在任何情況下,請注意in alist不檢查子字符串。 strings__contains__做子字符串測試,但我不知道任何內置類傳播測試到組件字符串。

由於Divakar顯示了numpy函數的集合,它將字符串方法應用於數組的各個元素。

In [42]: np.char.find(bar, 'aa') 
Out[42]: array([ 0, 0, -1]) 

文檔字符串:
此模塊包含矢量串 操作和方法的一組功能。 defchararray的首選別名是numpy.char

對於操作這樣我覺得np.char速度大約相同與:

In [49]: np.frompyfunc(lambda x: x.find('aa'), 1, 1)(bar) 
Out[49]: array([0, 0, -1], dtype=object) 

In [50]: np.frompyfunc(lambda x: 'aa' in x, 1, 1)(bar) 
Out[50]: array([True, True, False], dtype=object) 

進一步的試驗表明,ndarray__contains__flat版本數組的操作 - 即,形狀沒有按」不會影響其行爲。

相關問題