Python 数组的最长前缀等于一个值
我有表示序列分段的字符串的NumPy数组Python 数组的最长前缀等于一个值,python,numpy,Python,Numpy,我有表示序列分段的字符串的NumPy数组B是感兴趣的段的开始,I它的延续,O在任何段之外。例如,在以下数组中,有三个感兴趣的段: >>> y array(['B', 'I', 'I', 'O', 'B', 'I', 'O', 'O', 'B', 'O'], dtype='|S1') 我可以很容易地找到以np开头的片段。其中(y==“B”)[0]。但现在我还试图找到段的长度,即最长前缀的长度等于I。我可以使用itertools执行此操作。takewhile: &g
B
是感兴趣的段的开始,I
它的延续,O
在任何段之外。例如,在以下数组中,有三个感兴趣的段:
>>> y
array(['B', 'I', 'I', 'O', 'B', 'I', 'O', 'O', 'B', 'O'],
dtype='|S1')
我可以很容易地找到以np开头的片段。其中(y==“B”)[0]
。但现在我还试图找到段的长度,即最长前缀的长度等于I
。我可以使用itertools执行此操作。takewhile
:
>>> from itertools import takewhile
>>> lengths = [1 + sum(1 for _ in takewhile(lambda x: x == "I", y[start + 1:]))
... for start in np.where(y == "B")[0]]
>>> lengths
[3, 2, 1]
老实说,这很好,但是有没有一种矢量化的方法来实现这一点?搜索排序可以帮助您:
>>> y
array(['B', 'I', 'I', 'O', 'B', 'I', 'O', 'O', 'B', 'O'],
dtype='|S1')
>>> start=np.where(y=='B')[0]
>>> end=np.where(y=='O')[0]
>>> end[np.searchsorted(end,start)]-start
array([3, 2, 1])
另一种方法:
>>> mask=np.concatenate(([True],(np.diff(end)!=1)))
>>> mask
array([ True, True, False, True], dtype=bool)
>>> end[mask]-start
array([3, 2, 1])
段以A
'B'
开头:
starts = np.where(y == 'B')[0]
当'B'
或'I'
后面跟有'I'
以外的内容时,段结束,或在序列的末尾:
ends = np.where(((y == 'B') | (y == 'I')) & np.r_[y[1:] != 'I', len(y)])[0]
这将给出段长度:
(ends - starts) + 1
array([3, 2, 1])
编辑:这里有一个更简单的方法:在末尾插入一个虚构的
B
,然后取(真实的或虚构的)B
s的位置差,不包括O
s:
np.diff(np.where(np.r_[y[y != 'O'], ['B']] == 'B')[0])
array([3, 2, 1])
出于好奇,有没有列出所有numpy方法在某个地方的规模。大多数只是线性时间,但搜索和排序显然不能。