如何获取numpy数组值的累计计数?

2 投票
1 回答
1430 浏览
提问于 2025-04-16 07:31

好的,我觉得这个问题应该比较简单,但我的numpy技能还不够强。我有一个整数数组A,它重复了N次。我想要一个统计,记录每个元素被使用的次数。

比如,下面这个(我把数组重新排列了一下,让重复的部分更明显):

[0, 1, 2, 0, 0, 1, 0] \
[0, 1, 2, 0, 0, 1, 0] ...

会变成:

[0, 0, 0, 1, 2, 1, 3] \
[4, 2, 1, 5, 6, 3, 7]

这段Python代码可以做到,虽然方法不太优雅,而且速度也比较慢:

def running_counts(ar):
    from collections import defaultdict
    counts = defaultdict(lambda: 0)
    def get_count(num):
        c = counts[num]
        counts[num] += 1
        return c
    return [get_count(num) for num in ar]

差不多能想到一个numpy的小技巧来解决这个问题,但还没完全想明白。

更新

好的,我做了一些改进,但还是依赖于上面的running_counts方法。下面这个方法速度更快,感觉也更接近我想要的:

def sample_counts(ar, repititions):
    tile_bins = np.histogram(ar, np.max(ar)+1)[0]
    tile_mult = tile_bins[ar]
    first_steps = running_counts(ar)
    tiled = np.tile(tile_mult, repititions).reshape(repititions, -1)
    multiplier = np.reshape(np.arange(repititions), (repititions, 1))
    tiled *= multiplier
    tiled += first_steps
    return tiled.ravel()

有没有什么优雅的办法可以去掉running_counts()?现在速度还不错,只是感觉有点不够优雅。

1 个回答

3

这是我对这个问题的看法:

def countify2(ar):
    ar2 = np.ravel(ar)
    ar3 = np.empty(ar2.shape, dtype=np.int32)
    uniques = np.unique(ar2)
    myarange = np.arange(ar2.shape[0])
    for u in uniques:
        ar3[ar2 == u] = myarange
    return ar3

这个方法在元素数量远远超过独特元素数量的时候效果最好。

是的,这个方法和Sven的有点像,但我确实是在他发帖之前就写好了。我只是需要去别的地方。

撰写回答