我有以下数组:
# 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,1,2,1,1,2,3]
我们开始对每个元素计数,如果再次出现一个元素,则增加 count ,直到到达数组末尾。此元素特定的计数应作为结果返回。
我们应该如何使用NumPy内置函数来实现这一目标?我尝试使用numpy.bincount
,但结果不理想。
答案 0 :(得分:3)
不确定您会找到内置的,因此这是使用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进行排序,因为我们需要索引才能最终返回原始顺序。在这里重要的是要有一个稳定的排序,因此要使用慢速合并排序。
对元素进行排序后,运行计数将形成“锯齿”模式。创建该矢量的矢量化方法是观察锯齿的差异具有“跳跃”值,新锯齿开始于该锯齿,其他任何地方都存在。因此,这很容易构造。