2016-11-18 78 views
2

考虑阵列a累计argmax

np.random.seed([3,1415]) 
a = np.random.randint(0, 10, (10, 2)) 
a 

array([[0, 2], 
     [7, 3], 
     [8, 7], 
     [0, 6], 
     [8, 6], 
     [0, 2], 
     [0, 4], 
     [9, 7], 
     [3, 2], 
     [4, 3]]) 

什么是量化的方式来获得累计argmax?

array([[0, 0], <-- both start off as max position 
     [1, 1], <-- 7 > 0 so 1st col = 1, 3 > 2 2nd col = 1 
     [2, 2], <-- 8 > 7 1st col = 2, 7 > 3 2nd col = 2 
     [2, 2], <-- 0 < 8 1st col stays the same, 6 < 7 2nd col stays the same 
     [2, 2], 
     [2, 2], 
     [2, 2], 
     [7, 2], <-- 9 is new max of 2nd col, argmax is now 7 
     [7, 2], 
     [7, 2]]) 

这里是一个非量化的方式来做到这一点。

请注意,随着窗口的扩展,argmax适用于不断增长的窗口。

pd.DataFrame(a).expanding().apply(np.argmax).astype(int).values 

array([[0, 0], 
     [1, 1], 
     [2, 2], 
     [2, 2], 
     [2, 2], 
     [2, 2], 
     [2, 2], 
     [7, 2], 
     [7, 2], 
     [7, 2]]) 

回答

3

提到下面是执行相当没好气向量化纯NumPy的溶液:

def cumargmax(a): 
    m = np.maximum.accumulate(a) 
    x = np.repeat(np.arange(a.shape[0])[:, None], a.shape[1], axis=1) 
    x[1:] *= m[:-1] < m[1:] 
    np.maximum.accumulate(x, axis=0, out=x) 
    return x 

然后我们有:

>>> cumargmax(a) 
array([[0, 0], 
     [1, 1], 
     [2, 2], 
     [2, 2], 
     [2, 2], 
     [2, 2], 
     [2, 2], 
     [7, 2], 
     [7, 2], 
     [7, 2]]) 

对具有数千到数百万个值的数组进行一些快速测试表明,这比在Python级别循环(隐式或显式)快10-50倍。

+0

这是我的要求http://stackoverflow.com/a/40680265/2336654 – piRSquared

1

我不能想到一种方法来向两个列轻松地向量化这种方法;但是,如果列数相对于行数,这不应该是一个问题,一个for循环应该能满足该轴小:

import numpy as np 
import numpy_indexed as npi 
a = np.random.randint(0, 10, (10)) 
max = np.maximum.accumulate(a) 
idx = npi.indices(a, max) 
print(idx) 
1

我想提出一个计算累计argmax功能对于1d数组,然后将其应用于所有列。这是代码:

import numpy as np 

np.random.seed([3,1415]) 
a = np.random.randint(0, 10, (10, 2)) 

def cumargmax(v): 
    uargmax = np.frompyfunc(lambda i, j: j if v[j] > v[i] else i, 2, 1) 
    return uargmax.accumulate(np.arange(0, len(v)), 0, dtype=np.object).astype(v.dtype) 

np.apply_along_axis(cumargmax, 0, a) 

其原因转换为np.object然后转换回为numpy的1.9一种解决方法,如在generalized cumulative functions in NumPy/SciPy?

+1

请注意,frompyfunc仅向量化语法;不是表现。这将具有与天真的python循环相当的性能。 –