我们说我有两个大的文字串,我分成了几个字:
import numpy as np
s1 = 'this is a test test test'
s2 = 'that is another test'
terms1 = np.array(s1.split())
terms2 = np.array(s2.split())
现在terms1
为['this', 'is', 'a', 'test', 'test', 'test']
,terms2
为['that', 'is', 'another', 'test']
。
我现在想要为每个唯一的单词分配一个ID,然后为每个terms
- 一个包含相应ID的向量得到一个数组,即指向公共"词汇表" terms1
和terms2
:
vocab = np.unique(np.concatenate((terms1, terms2)))
# yields ['a', 'another', 'is', 'test', 'that', 'this']
ind1 = [np.where(t == vocab)[0][0] for t in terms1]
# yields indices into "vocab": [5, 2, 0, 3, 3, 3]
ind2 = [np.where(t == vocab)[0][0] for t in terms2]
# yields indices into "vocab": [4, 2, 1, 3]
这基本上有效。但是,在for循环中使用np.where
似乎效率低下,我想知道NumPy是否有更好的方法来做这些事情?
答案 0 :(得分:6)
使用np.unique
的return_inverse
参数,然后使用连接输入的长度拆分返回的逆数组:
In [13]: vocab, inv = np.unique(np.concatenate((terms1, terms2)), return_inverse=True)
In [14]: inv[:len(terms1)]
Out[14]: array([5, 2, 0, 3, 3, 3])
In [15]: inv[len(terms1):]
Out[15]: array([4, 2, 1, 3])
答案 1 :(得分:2)
您可以使用broadcasting
一次进行所有比较:
In [23]: np.where(terms1[:, None] == vocab)[1]
Out[23]: array([5, 2, 0, 3, 3, 3])
In [24]: np.where(terms2[:, None] == vocab)[1]
Out[24]: array([4, 2, 1, 3])
答案 2 :(得分:0)
如果您使vocab
列表,则可以使用index()
:
vocab_list = list(np.unique(np.concatenate((terms1, terms2))))
ind1 = [vocab_list.index(t) for t in terms1]
在我的速度测试中,这似乎比np.where()
快,但我不确定大型列表会发生什么。