我假設你正在尋找一個numpy特定的解決方案,而不是一個簡單的列表理解或for循環。一種方法可能是使用rolling window技術來搜索適當大小的窗口。這裏的rolling_window功能:
>>> def rolling_window(a, size):
... shape = a.shape[:-1] + (a.shape[-1] - size + 1, size)
... strides = a.strides + (a. strides[-1],)
... return numpy.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)
...
然後,你可以做這樣的事情
>>> a = numpy.arange(10)
>>> numpy.random.shuffle(a)
>>> a
array([7, 3, 6, 8, 4, 0, 9, 2, 1, 5])
>>> rolling_window(a, 3) == [8, 4, 0]
array([[False, False, False],
[False, False, False],
[False, False, False],
[ True, True, True],
[False, False, False],
[False, False, False],
[False, False, False],
[False, False, False]], dtype=bool)
爲了使這真的很有用,你必須使用all
,以減少它沿軸1:
>>> numpy.all(rolling_window(a, 3) == [8, 4, 0], axis=1)
array([False, False, False, True, False, False, False, False], dtype=bool)
然後你可以使用,但是你會使用一個布爾數組。一個簡單的方法來獲得索引列:
>>> bool_indices = numpy.all(rolling_window(a, 3) == [8, 4, 0], axis=1)
>>> numpy.mgrid[0:len(bool_indices)][bool_indices]
array([3])
對於列表,你可以調整這些rolling window迭代器之一來使用類似的方法。
對於非常大陣列和子陣,你可以節省內存這樣的:
>>> windows = rolling_window(a, 3)
>>> sub = [8, 4, 0]
>>> hits = numpy.ones((len(a) - len(sub) + 1,), dtype=bool)
>>> for i, x in enumerate(sub):
... hits &= numpy.in1d(windows[:,i], [x])
...
>>> hits
array([False, False, False, True, False, False, False, False], dtype=bool)
>>> hits.nonzero()
(array([3]),)
在另一方面,這將可能會比較慢。如果沒有測試,速度慢多少?請參閱Jamie的另一個節省內存選項的答案,該選項必須檢查誤報。我想象這兩種解決方案之間的速度差異將在很大程度上取決於輸入的性質。
你可以將列表轉換爲字符串進行比較嗎? 'x =''。join(str(x)for x in a)'然後使用find方法和結果字符串?還是他們必須保持清單? – danem