给定列表中指定项目的位置,逐渐将一个添加到索引列表

Incrementally adds one to a list of indices given positions of specified item in list

给定令牌列表,输入:

>>> tokenized_text = "[CLS] my dog is cute [SEP] he likes slack ##ing [SEP]".split()
>>> tokenized_text 
['[CLS]', 'my', 'dog', 'is', 'cute', '[SEP]', 'he', 'likes', 'slack', '##ing', '[SEP]']

目标是为每个 [SEP] 从左到右创建一个索引,找到 [SEP] 个标记,然后在每个 [SEP] 之后递增地添加 1,因此上面 tokenize_text 列表的期望输出索引是:

[0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1]

我试过:

# Find the indices of `[SEP]`.
>>> sep_indices = np.array(np.where(np.array(tokenized_text) == "[SEP]"))[0]
>>> sep_indices
array([ 5, 10])

>>> prev = 0
>>> out =[]
>>> for i, idx in enumerate(sep_indices):
...     for _ in range(idx-prev):
...         out.append(i)
...     prev = idx
... 
>>> out = [0] + out[:-1]
>>> out
[0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1]

但是有没有更简单的方法来实现正确的输出?

使用 NumPy 的更简单和矢量化的方式 -

In [116]: a = np.asarray(tokenized_text)

In [117]: m = a == "[SEP]"

In [118]: m.cumsum()-m
Out[118]: array([0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1])

cumsum呢?您的问题输出不一致,但这种差一错误应该很容易修复。

>>> np.cumsum(np.array(tokenized_text) == "[SEP]")
array([0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2])

对于那些因为某些原因不need/want使用numpy的人,还有itertools.accumulate

>>> from itertools import accumulate
>>> list(accumulate(int(elem == '[SEP]') for elem in tokenized_text))
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2]