我们可以拉平所有子列表元素给我们一维数组。然后,我们只需在扁平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