Python 计算a";“移动计数和”;关于NumPy数组

Python 计算a";“移动计数和”;关于NumPy数组,python,numpy,counting,numpy-ndarray,Python,Numpy,Counting,Numpy Ndarray,我有以下阵列: # input In [77]: arr = np.array([23, 45, 23, 0, 12, 45, 45]) # result In [78]: res = np.zeros_like(arr) 现在,我想计算唯一元素的移动和,并将其存储在res数组中 具体来说,res数组应该是: In [79]: res Out[79]: array([1, 1, 2, 1, 1, 2, 3]) [23,45,23,0,12,45,45] [1,1,2,1,1,2,3] 我

我有以下阵列:

# input
In [77]: arr = np.array([23, 45, 23, 0, 12, 45, 45])

# result
In [78]: res = np.zeros_like(arr)
现在,我想计算唯一元素的移动和,并将其存储在
res
数组中

具体来说,
res
数组应该是:

In [79]: res
Out[79]: array([1, 1, 2, 1, 1, 2, 3])

[23,45,23,0,12,45,45]
[1,1,2,1,1,2,3]

我们开始计数每个元素,如果元素重新出现,则增加计数,直到到达数组的末尾。此元素特定的计数应作为结果返回



我们应该如何使用NumPy内置函数来实现这一点?我尝试使用
numpy.bincount
,但它会产生不想要的结果。

不确定是否会找到内置的,因此这里有一个使用argsort的自制软件

def running_count(arr):
    idx = arr.argsort(kind='mergesort')
    sarr = arr[idx]
    neq = np.where(sarr[1:] != sarr[:-1])[0] + 1
    run = np.ones(arr.shape, int)
    run[neq[0]] -= neq[0]
    run[neq[1:]] -= np.diff(neq)
    res = np.empty_like(run)
    res[idx] = run.cumsum()
    return res
例如:

>>> running_count(arr)
array([1, 1, 2, 1, 1, 2, 3])
>>> running_count(np.array(list("xabaaybeeetz")))
array([1, 1, 1, 2, 3, 1, 2, 1, 2, 3, 1, 1])
解释者:

我们首先使用argsort进行排序,因为我们需要索引最终返回到原始顺序。这里有一个稳定的排序很重要,因此使用慢速合并排序

元素排序后,运行计数将形成“锯齿”模式。创建此项的矢量化方法是观察锯齿的差异在新齿开始的位置和其他位置具有“跳跃”值。因此,这是建设的正确方向