将唯一的 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 在此设置中速度更快
是否有一种简单而有效的方法来连接两个具有计数器的唯一 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 在此设置中速度更快