Numpy逐块减少操作

Mar*_*ito 9 python arrays indexing reduce numpy

我认为自己是一个经验丰富的numpy用户,但我无法找到解决以下问题的方法.假设有以下数组:

# sorted array of times
t = numpy.cumsum(numpy.random.random(size = 100))
#  some values associated with the times
x = numpy.random.random(size=100)
# some indices into the time/data array
indices = numpy.cumsum(numpy.random.randint(low = 1, high=10,size = 20)) 
indices = indices[indices <90] # respect size of 100
if len(indices) % 2: # make number of indices even
    indices = indices[:-1]

# select some starting and end indices
istart = indices[0::2]
iend   = indices[1::2]
Run Code Online (Sandbox Code Playgroud)

我现在想要的是在x给定由istart和表示的区间的情况下减少值数组iend.即

# e.g. use max reduce, I'll probably also need mean and stdv
what_i_want = numpy.array([numpy.max(x[is:ie]) for is,ie in zip(istart,iend)])
Run Code Online (Sandbox Code Playgroud)

我已经google了很多,但我能找到的stride_tricks只是块操作,只允许常规块.我没有在没有执行pyhthon循环的情况下找到解决方案:-(在我的实际应用程序中,阵列要大得多,性能也很重要,所以我numba.jit暂时使用它.

有什么numpy功能我错过了能够做到吗?

wfl*_*nny 7

你看过了ufunc.reduceat吗?有了np.maximum,你可以这样做:

>>> np.maximum.reduceat(x, indices)
Run Code Online (Sandbox Code Playgroud)

它产生沿切片的最大值x[indices[i]:indices[i+1]].为了得到你想要的东西(x[indices[2i]:indices[2i+1]),你可以做到

>>> np.maximum.reduceat(x, indices)[::2]
Run Code Online (Sandbox Code Playgroud)

如果你不介意额外的计算x[inidices[2i-1]:indices[2i]].这产生以下结果:

>>> numpy.array([numpy.max(x[ib:ie]) for ib,ie in zip(istart,iend)])
array([ 0.60265618,  0.97866485,  0.78869449,  0.79371198,  0.15463711,
        0.72413702,  0.97669218,  0.86605981])

>>> np.maximum.reduceat(x, indices)[::2]
array([ 0.60265618,  0.97866485,  0.78869449,  0.79371198,  0.15463711,
        0.72413702,  0.97669218,  0.86605981])
Run Code Online (Sandbox Code Playgroud)