我們可以拉平所有子列表元素給我們一維數組。然後,我們只需在扁平1D陣列中的每個子列表的範圍內尋找任何發生的'c'
。因此,根據這一理念,我們可以使用兩種方法,基於如何計算任何c
的發生。
方法1:一種方法與np.bincount
-
lens = np.array([len(i) for i in nested_list])
arr = np.concatenate(nested_list)
ids = np.repeat(np.arange(lens.size),lens)
out = np.bincount(ids, arr=='c')!=0
因爲,如問題所說,nested_list
不會跨越迭代變化,我們可以重新使用的一切,只爲循環的最後步。
方法2:與np.add.reduceat
從以前的一個重用arr
和lens
另一種方法 -
grp_idx = np.append(0,lens[:-1].cumsum())
out = np.add.reduceat(arr=='c', grp_idx)!=0
當通過words
列表循環,我們能保持這種方法矢量在最後一步通過沿軸使用np.add.reduceat
並使用broadcasting
給我們一個2D
數組布爾,就像這樣 -
np.add.reduceat(arr==np.array(words)[:,None], grp_idx, axis=1)!=0
樣品運行 -
In [344]: nested_list
Out[344]: [['a', 'b', 'c'], ['a', 'b'], ['b', 'c'], ['c']]
In [345]: words
Out[345]: ['c', 'b']
In [346]: lens = np.array([len(i) for i in nested_list])
...: arr = np.concatenate(nested_list)
...: grp_idx = np.append(0,lens[:-1].cumsum())
...:
In [347]: np.add.reduceat(arr==np.array(words)[:,None], grp_idx, axis=1)!=0
Out[347]:
array([[ True, False, True, True], # matches for 'c'
[ True, True, True, False]]) # matches for 'b'
如果列表是靜態的,並且您執行了很多操作,則可以索引一次並使用該索引。由於索引本身很昂貴,因此一次傳遞就不值得。 – tdelaney
一次,作爲'文字',你會只有一個字符或可能有多個? – Divakar
實際上,單詞可以有更多的字符。如果words = ['c','b'],那麼我需要2個布爾數組:result = [[1,0,1,1],[1,1,1,0]]。 – jevanio