【问题标题】:Find maximum value and indices of a maximum without using max built in functions在不使用 max 内置函数的情况下查找最大值和最大值的索引
【发布时间】:2020-09-03 00:36:43
【问题描述】:

正如标题所说,我试图在不使用内置 max 函数的任何变体的情况下找到参数的最大值和位置。

我能够将它拼凑成一个基本的np.array,但我很难将它转换成一个矩阵......我认为是因为它的索引方式。

这是我为np.array 准备的:

a = np.array((1,2,2,3,4,3,2,1,4,3))

def argmax(x):
    maximum = 0
    for i in range(len(x)):
        if x[i] > maximum: maximum = x[i]
    pos = np.argwhere(x == maximum)[0][0]
    return(print('The maximum value of the array is', maximum, 'and is located at index', pos))

argmax(a)

数组的最大值为4,位于索引4处。

我正在尝试为任何大小的矩阵创建类似的东西,而不使用内置的 max 函数。有人可以帮我解决这个功能并帮助我理解基本数组和矩阵之间索引的区别吗?

【问题讨论】:

  • 您不能在迭代时跟踪imaximum(如果需要,还可以跟踪j 列)? argwhere 看起来需要做很多额外的工作。将此数组视为列表或列表列表。事实上,当这样迭代时,使用列表列表会更快。
  • 您的阵列最多是二维的还是更高维度的?
  • 另外,如果 max 发生多次,你想要一个随机最大值还是全部的位置?您的数组是否包含所有非负值?
  • @hpaulj。我已经发布了一个相当笼统的答案。我认为使用数组肯定更简单,因为您可以使用掩码。
  • 大家好,感谢您的快速回复!这些都是二维数组。如果它出现多次,我更喜欢最大值的所有位置。没有负值。

标签: python arrays function numpy matrix


【解决方案1】:

这适用于一维数组和二维数组:

import numpy as np
import math

matrix = np.arange(20).reshape(4, 5)
print(matrix)
# Important
matrix = np.atleast_2d(matrix)
# set maximum to -inf
maximum = -math.inf
# Search maximum
for j in range(matrix.shape[1]):
    for i in range(matrix.shape[0]):
        maximum = matrix[i][j] if matrix[i][j] > maximum else maximum

# More than 1 maximum, take the first one?
pos = np.argwhere(matrix == maximum)[0]
print(
    f"The maximum value of the array is: {maximum}, located at: row {pos[0]}, column {pos[1]}"
)

输出:

[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]]
The maximum value of the array is: 19, located at: row 3, column 4

【讨论】:

  • 这太完美了!就像我理解的那样,j in range 循环通过列,i in range 循环通过行?
  • @smcconn5 是的,j 代表列,i 代表行
【解决方案2】:

我假设您想沿给定轴找到最大值。否则,请执行np.unravel_index(argmax(a.ravel()), a.shape)

首先让我们定义一个沿给定维度步进并跟踪最大值和它们出现的索引的函数:

def argmax(a, axis):
    # index
    cur = [slice(None) for _ in range(a.ndim)]
    cur[axis] = 0

    # trackers
    val = a[tuple(index)]
    ind = np.zeros(val.shape, dtype=int)

    # loop
    for i in range(1, a.shape[axis]):
        index[axis] = i
        v = a[tuple(index)]
        mask = v > val
        val[mask] = v[mask]
        ind[mask] = i
    return ind

这将沿axis 返回索引。如果您想获取其他索引,请执行以下操作

all_indices = list(np.indices(a.shape))
all_indices[axis] = ind
all_indices = tuple(all indices)

或者,

all_indices = [slice(None) for _ range(a.ndim)]
all_indices[axis] = ind
all_indices = tuple(all indices)

此函数会跳过一些极端情况,例如 a.shape[axis] == 0a.ndim == 0,但您可以通过简单的初步测试轻松处理它们。

您还可以使用递归调用对axis=None 进行特殊处理,如答案开头所示。

如果您想同时允许多个轴,请将它们全部交换到最后,然后将它们重新整形为单个轴。所以是axis=None 和正常处理的混合体。

【讨论】:

    【解决方案3】:

    这是一种对 任何形状和尺寸 数组执行此操作的方法(它假定值是非负数,因为您使用 0 初始化最大值并仅返回最大值的第一个发生率,就像您在原始答案。当然您可以轻松更改它们):

    def argmax(x):
        maximum = 0
        for i, v in enumerate(x.reshape(-1)):
            if v > maximum: 
                maximum = v
                pos = i
        print('The maximum value of the array is', maximum, 'and is located at index', np.unravel_index(pos, x.shape))
    
    argmax(a)
    

    例子:

    a = np.random.randint(0,10,(3,4))
    #[[7 6 2 6]
    # [7 2 0 5]
    # [4 0 8 7]]
    

    输出:

    The maximum value of the array is 8 and is located at index (2, 2)
    

    【讨论】:

    • print 返回None。您的意思是在函数之外打印吗?
    • @MadPhysicist 这是真的。甚至没有从 OP 的代码中注意到这一点。我认为这是他们想要的输出,但真正返回是无关紧要的。编辑它。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-28
    • 2018-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多