矢量化解决方案(教学风格,易于理解)
我们可以通过使用鉴别器索引扩充数组来将其向量化,例如a
tagged0
和b
tagged 1
:
a_t = np.vstack((a, np.zeros_like(a)))
b_t = np.vstack((b, np.ones_like(b)))
现在,让我们组合和排序:
c = np.hstack((a_t, b_t))[:, np.argsort(np.hstack((a, b)))]
array([[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 13, 14, 15, 17, 19, 21, 23],
[ 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1]])
你可以看到现在元素是有序的,但保留了它们的标签,所以我们可以看到哪些元素来自a
和来自b
。
因此,让我们选择第一个元素以及标签从0
(for a
) 变为1
(for b
) 并再次返回的每个元素:
c[:, np.concatenate(([True], c[1, 1:] != c[1, :-1]))][0]
array([ 1, 5, 7, 13, 17, 19])
高效的矢量化解决方案
您可以通过将项目及其标签保存在单独(但并行)的数组中来稍微更有效地执行此操作:
ab = np.hstack((a, b))
s = np.argsort(ab)
t = np.hstack((np.zeros_like(a), np.ones_like(b)))[s]
ab[s][np.concatenate(([True], t[1:] != t[:-1]))]
array([ 1, 5, 7, 13, 17, 19])
这比上述解决方案效率略高;我得到的平均时间是 45 微秒,而不是 90 微秒,尽管您的条件可能会有所不同。