3

给定一个 numpy 数组,例如a = [0, 3, 2, 4, 0, 2, 3, 1, 1, 6, 2],是否有一种简单的方法可以记录每 3 个值的最大值?数组的长度可能不是 3 的倍数。在这种情况下,结果应该是b = [3, 4, 3, 6].

我想到了一些类似的东西

b = [max(a[k:k+3]) for k in range(0, len(a), 3)

但它没有考虑 3 的最后一个倍数之后的值(它应该)。

我还考虑过重新排列 numpy 数组,使其具有 3*n 行,并使用 numpy 模块沿正确的轴取最大值,但是,我不知道如何处理最后一个之后的值3的倍数。

4

3 回答 3

4

方法#1

我们可以 np.ufunc.reduceat用来执行这种分组/间隔的归约操作。因此,要获得maximum每个区间内的值,我们将拥有 -

W = 3 # group width
np.maximum.reduceat(a,np.r_[:len(a):W])

样品运行 -

In [166]: a
Out[166]: array([0, 3, 2, 4, 0, 2, 3, 1, 1, 6, 2])

In [167]: W = 3

In [168]: np.maximum.reduceat(a,np.r_[:len(a):W])
Out[168]: array([3, 4, 3, 6])

方法#2

这是另一个slicing-

def max_interval_slice(a, W=3):
    n = len(a)//W
    max0 = a[:n*W].reshape(-1,W).max(1)
    if n*W==len(a):
        return max0
    else:
        return np.r_[max0, np.max(a[n*W:])]

样品运行 -

# Input array of length NOT multiple of width=3
In [99]: a
Out[99]: array([0, 3, 2, 4, 0, 2, 3, 1, 1, 6, 2])

In [100]: max_interval_slice(a, W=3)
Out[100]: array([3, 4, 3, 6])

# Input array of length multiple of width=3
In [95]: a = a[:9]

In [96]: max_interval_slice(a, W=3)
Out[96]: array([3, 4, 3])
于 2018-07-10T19:58:13.927 回答
2

为了最小化您需要做的重新分配量,您可以计算适合 3 的倍数的所有元素的最大值,然后计算余数的最大值。此解决方案并不那么简单,但它不会创建不必要的数据副本:

n = 3  # The group width
prefix, suffix = divmod(a.size, n)
output = np.empty(prefix + bool(suffix))
a[:n * prefix].reshape(-1, n).max(axis=1, out=output[:prefix])
if suffix:
    output[-1] = a[-suffix:].max()
于 2018-07-10T20:05:03.990 回答
2

首次使用np.pad

a = np.pad(a, [0, 1], mode='constant')

然后reshapemax

>>> np.max(a.reshape(-1, 3), axis=1)
array([3, 4, 3, 6])

为了概括这一点,只需计算填充以重塑到所需的尺寸。

于 2018-07-10T19:45:46.917 回答