将唯一的 numpy 数组与计数器连接起来

Concatenate unique numpy arrays with counters

是否有一种简单而有效的方法来连接两个具有计数器的唯一 numpy 数组?

示例:

values1 = np.array(['host1', 'host2', 'host3', 'host6'])
counts1 = np.array([2,5,2,4])

values2 = np.array(['host3', 'host1', 'host4'])
counts2 = np.array([5,7,1])

我想要这样的结果:

values_res = np.array(['host1', 'host2', 'host3', 'host6', 'host4'])
counts_res = np.array([9,5,7,4,1])

它们不需要排序,但 values_res 确实需要是唯一的。

我可以遍历数组中的元素,但效率不高。我想以某种方式使用矢量化。

您可以利用计数器可以加在一起的事实。压缩每一对,制作一个计数器,将它们加在一起,然后打开包装。

from collections import Counter

values1 = np.array(['host1', 'host2', 'host3'])
counts1 = np.array([2,5,2])

values2 = np.array(['host3', 'host1', 'host4'])
counts2 = np.array([5,7,1])


values_res, counts_res = zip(*dict(Counter(dict(zip(values1,counts1))) + Counter(dict(zip(values2,counts2)))).items())

这可能更快(特别是对于较大的数组)并且是有序的:

values_res, idx = np.unique(np.hstack((values1, values2)), return_inverse=True)
counts_res = np.bincount(idx, np.hstack((counts1, counts2)))

输出:

['host1' 'host2' 'host3' 'host4' 'host6']
[9. 5. 7. 1. 4.]

比较 使用 benchit:

#@Ehsan's solution
def m1(values1, values2, counts1, counts2):
  values_res, idx = np.unique(np.hstack((values1, values2)), return_inverse=True)
  counts_res = np.bincount(idx, np.hstack((counts1, counts2)))
  return values_res, counts_res

#@Chris's solution
def m2(values1, values2, counts1, counts2):

  values_res, counts_res = zip(*dict(Counter(dict(zip(values1,counts1))) + Counter(dict(zip(values2,counts2)))).items())
  return values_res, counts_res


in_ = {n:[np.random.choice(values_res, n), np.random.choice(values_res, n), np.random.randint(1,100,n), np.random.randint(1,100,n)] for n in [10,100,1000,10000]}

输出:

m1 在此设置中速度更快