我使用Python numpy
。
我有一个numpy数组may_a
:
may_a = numpy.array([False, True, False, True, True, False, True, False, True, True, False])
我有一个numpy数组may_b
:
may_b = numpy.array([False,True,True,False])
我需要在数组may_b
中找到数组may_a
。
在输出中我需要获取出现的索引。
out_index=[2,7]
有人可以建议,如何获得out_index
?
答案 0 :(得分:5)
更酷的方法,可能效果不好,但适用于任何dtype,是使用as_strided
:
In [2]: from numpy.lib.stride_tricks import as_strided
In [3]: may_a = numpy.array([False, True, False, True, True, False,
...: True, False, True, True, False])
In [4]: may_b = numpy.array([False,True,True,False])
In [5]: a = len(may_a)
In [6]: b = len(may_b)
In [7]: a_view = as_strided(may_a, shape=(a - b + 1, b),
...: strides=(may_a.dtype.itemsize,) * 2)
In [8]: a_view
Out[8]:
array([[False, True, False, True],
[ True, False, True, True],
[False, True, True, False],
[ True, True, False, True],
[ True, False, True, False],
[False, True, False, True],
[ True, False, True, True],
[False, True, True, False]], dtype=bool)
In [9]: numpy.where(numpy.all(a_view == may_b, axis=1))[0]
Out[9]: array([2, 7])
你必须要小心,因为尽管a_view
是may_a
数据的视图,但在将其与may_b
进行比较时,(a - b + 1) * b
的临时数组是已创建,这可能是大a
和b
s。
答案 1 :(得分:4)
编辑以下代码允许执行基于卷积的相等检查。它将True
映射到1
和False
映射到-1
。它还会反转b
,这是正常工作所必需的:
def search(a, b) :
return np.where(np.round(fftconvolve(a * 2 - 1, (b * 2 - 1)[::-1],
mode='valid') - len(b)) == 0)[0]
我已经检查过,它为各种随机输入提供了与as_strided
方法相同的输出。我也有时间接近,并且卷积只开始用大约256件物品的大量搜索令牌付出代价。
看起来有点矫枉过正,但使用布尔数据你可以使用(滥用?)卷积:
In [8]: np.where(np.convolve(may_a, may_b.astype(int),
...: mode='valid') == may_b.sum())[0]
Out[8]: array([2, 7])
对于较大的数据集,使用scipy.signal.fftconvolve
可能会更快:
In [13]: np.where(scipy.signal.fftconvolve(may_a, may_b,
....: mode='valid') == may_b.sum())[0]
Out[13]: array([2, 7])
你必须小心,因为输出现在是浮点数,舍入可能会破坏相等检查:
In [14]: scipy.signal.fftconvolve(may_a, may_b, mode='valid')
Out[14]: array([ 1., 1., 2., 1., 1., 1., 1., 2.])
所以你可能会对以下内容更好:
In [15]: np.where(np.round(scipy.signal.fftconvolve(may_a, may_b, mode='valid') -
....: may_b.sum()) == 0)[0]
Out[15]: array([2, 7])
答案 2 :(得分:3)
这与string search problem非常相似。如果你想避免实现这些字符串搜索算法,你可以通过执行以下操作来滥用字符串搜索中构建的pythons,这非常快:
# I've added [True, True, True] at the end.
may_a = numpy.array([False, True, False, True, True, False, True, False, True, True, False, True, True, True])
may_b = numpy.array([False,True,True,False])
may_a_str = may_a.tostring()
may_b_str = may_b.tostring()
idx = may_a_str.find(may_b_str)
out_index = []
while idx >= 0:
out_index.append(idx)
idx = may_a_str.find(may_b_str, idx+1)
这应该适用于布尔数组。如果你想将这种方法用于另一种数组类型,你需要确保两个数组的步幅匹配,并按该步长划分out_index。
您也可以使用regular expression module代替循环来进行字符串搜索。
答案 3 :(得分:2)
这也适用于其他布尔数据:
In [1]: import numpy as np
In [2]: a = np.array([False, True, False, True, True, False, True, False, True, True, False])
In [3]: b = np.array([False,True,True,False])
In [4]: def get_indices(a, b):
...: window = len(b)
...: shape = a.shape[:-1] + (a.shape[-1] - window + 1, window)
...: strides = a.strides + (a.strides[-1],)
...: w = np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)
...: return np.where(np.all(np.equal(w,b),1) == True)[0]
In [5]: get_indices(a,b)
Out[5]: array([2, 7])
答案 4 :(得分:1)
我不确定numpy是否为此提供了一个功能。如果没有,这是一个解决方案:
import numpy
def searchListIndexs(array, target):
ret = []
iLimit = len(array)-len(target)+1
jLimit = len(target)
for i in range(iLimit):
for j in range(jLimit):
if array[i+j] != target[j]:
break
else:
ret.append(i)
return ret
may_a = numpy.array([False, True, False, True, True, False, True, False, True, True, False])
may_b = numpy.array([False,True,True,False])
out_index = searchListIndexs(may_a, may_b)
print out_index #If you are using Python 3, then use print(out_index) instead.