首页 > 解决方案 > Numpy:计算数组中索引出现的最佳方法

问题描述

我有一个数组indexs。它很长(>10k),每个 int 值都相当小(<100)。例如

indexs = np.array([1, 4, 3, 0, 0, 1, 2, 0]) # int index array
indexs_max = 4 # already known

现在我想计算每个索引值的出现次数(例如 0 表示 3 次,1 表示 2 次......),并counts得到np.array([3, 2, 1, 1, 1]). 我测试了4种方法如下:

UPDATE:_test4是@ Ch3steR的溶胶:


indexs = np.random.randint(0, 10, (20000,))
indexs_max = 9

def _test1():
    counts = np.zeros((indexs_max + 1, ), dtype=np.int32)
    for ind in indexs:
        counts[ind] += 1
    return counts

def _test2():
    counts = np.zeros((indexs_max + 1,), dtype=np.int32)
    uniq_vals, uniq_cnts = np.unique(indexs, return_counts=True)
    counts[uniq_vals] = uniq_cnts
    # this is because some value in range may be missing
    return counts

def _test3():
    therange = np.arange(0, indexs_max + 1)
    counts = np.sum(indexs[None] == therange[:, None], axis=1)
    return counts

def _test4():
    return np.bincount(indexs, minlength=indexs_max+1)

运行 500 次,它们的使用时间分别为32.499472856521606s0.31386804580688477s0.14069509506225586s0.017721891403198242s虽然_test3是最快的,但它使用额外的大内存。

所以我要求任何更好的方法。谢谢你 :) (@ Ch3steR )


UPDATE:np.bincount到目前为止似乎是最佳的。

标签: pythonnumpymatrixparallel-processingtorch

解决方案


您可以使用np.bincount来计算数组中的出现次数。

indexs = np.array([1, 4, 3, 0, 0, 1, 2, 0])
np.bincount(indexs)
# array([3, 2,  1,  1,  1])
#        0's 1's 2's 3's 4's count

有一个警告np.bincount(x).size == np.amax(x)+1

例子:

indexs = np.array([5, 10])
np.bincount(indexs)
# array([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1])
#                       5's            10's count

这是它将出现的次数为 0 到数组中的最大值,一种解决方法是

c = np.bincount(indexs) # indexs is [5, 10]
c = c[c>0]
# array([1,  1])
#        5's 10's count

如果您没有从 ie from0到的缺失值,your_max您可以使用np.bincount.

另一个警告:

来自文档:

计算非负整数数组中每个值的出现次数。


推荐阅读