简体   繁体   English

查找(并记录)numpy数组的切片的最大值

[英]Finding (and recording) the maximum values of slices of a numpy array

Given a numpy array such as a = [0, 3, 2, 4, 0, 2, 3, 1, 1, 6, 2] , is there a simple way to record the maximum value for every 3 values? 给定一个numpy数组,如a = [0, 3, 2, 4, 0, 2, 3, 1, 1, 6, 2] 0,3,2,4,0,2,3,1,1,6,2 a = [0, 3, 2, 4, 0, 2, 3, 1, 1, 6, 2] ,是否有一种简单的方法来记录每3个值的最大值? The length of the array may not be a multiple of 3. In this case, the result should be b = [3, 4, 3, 6] . 数组的长度可以不是3的倍数。在这种情况下,结果应该是b = [3, 4, 3, 6]

I thought of something along the lines of 我想到了一些类似的东西

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

but it doesn't take into account the values after the last multiple of 3 (which it should). 但它没有考虑3的最后一个倍数之后的值(它应该)。

I've also thought of rearranging the numpy array such that it has 3*n rows, and taking the maxima along the proper axis using the numpy module, but, again, I'm not sure how to deal with the values after the last multiple of 3. 我还想过重新排列numpy数组,使它有3 * n行,并使用numpy模块沿着正确的轴取最大值,但是,我再也不知道如何在最后一个之后处理这些值3的倍数。

Approach #1 方法#1

We can use np.ufunc.reduceat for performing such grouped/intervaled reduction operations. 我们可以使用np.ufunc.reduceat来执行这样的分组/ np.ufunc.reduceat减少操作。 Thus, to get maximum values within each interval, we would have - 因此,为了在每个区间内获得maximum ,我们将 -

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

Sample run - 样品运行 -

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])

Approach #2 方法#2

Here's another with slicing - 这是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:])]

Sample runs - 样品运行 -

# 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])

First use np.pad 首先使用np.pad

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

Then reshape and max 然后reshapemax

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

To generalize this, just calculate padding in order to reshape to the desired dimension. 为了概括这一点,只需计算填充以重新形成所需的尺寸。

To minimize the amount of reallocation you need to do, you can compute the maxima of all the elements that fit into a multiple of 3, and then the max of the remainder. 要最小化您需要执行的重新分配量,您可以计算适合3的倍数的所有元素的最大值,然后计算余数的最大值。 This solution is not as straightforward, but it does not create unnecessary copies of the data: 此解决方案不是那么简单,但它不会创建不必要的数据副本:

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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM