Numpy中无需循环的多轴argmax

Numpy中无需循环的多轴argmax

在本文中,我们将介绍使用Numpy在多个轴上无需循环执行argmax的方法。Argmax是返回数组中最大值的索引的函数。有时候需要找到多轴上的最大值,并且想要避免使用循环。这就是本文要解决的问题。

阅读更多:Numpy 教程

问题描述

我们有一个三维数组,每个维度的大小为5,3,4。我们需要找到每个纵向切片的最大元素,并返回其索引。

import numpy as np

np.random.seed(42)
a = np.random.randint(0, 20, (5, 3, 4))
print(a)

打印的数组如下所示:

[[[ 6 19 14 10]
  [ 7  6 18 10]
  [10  3  7  2]]

 [[ 1 11  5  1]
  [11 12  8  8]
  [14  3  2 13]]

 [[ 7 16  4 14]
  [18  3 16 17]
  [ 8  3 11  2]]

 [[ 1  0  7  6]
  [14  7  2 15]
  [ 6 19 18  7]]

 [[ 2 11  1  5]
  [19 14 19 12]
  [ 7 17  7 13]]]

我们想要得到的是每个纵向切片的最大元素的索引,即得到如下的结果:

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

解决方案

我们可以使用argmax执行单轴的最大值操作,但是如何在多轴上操作呢?我们可以使用transposereshape函数改变数组的维度。这里我们需要先确定我们要对哪些轴执行操作。对于当前的问题,我们需要的是对第二个和第三个轴执行操作,并返回一个只有两个轴的数组,每一行表示每个纵向切片的最大元素的索引。

b = a.transpose(1, 2, 0)  # 将第二个和第三个轴移动到前面,并将第一个轴移动到最后
print(b.shape)  # (3, 4, 5)

上述代码中,我们使用了transpose函数将第二个和第三个轴移动到前面,并将第一个轴移动到最后。这样我们得到了一个新的数组b,其形状为(3, 4, 5),对应于我们要对第二个和第三个轴执行操作。

现在我们需要将最后一个轴(即原来的第一个轴)移动到第二个位置,这可以通过reshape函数来实现。

c = b.reshape(b.shape[0], -1)
print(c.shape)  # (3, 20)

上述代码中,我们使用了reshape函数将(3, 4, 5)的数组b改变形状为(3, 20)的数组c,其中-1表示自动计算大小。

现在我们可以执行argmax函数来得到每个纵向切片的最大元素的索引。

idx = c.argmax(axis=1).reshape((b.shape[0], b.shape[1]))
print(idx)

上述代码中,我们使用了argmax函数在第二个轴上执行操作,并使用reshape函数将得到的结果改变形状为(3, 4),即每行表示每个纵向切片的最大元素的索引。

最后我们需要将得到的结果再次转换为原始数组的形式。我们需要将最后一个轴(即原来的第一个轴)移动回最后,然后对第二个和第三个轴执行transpose函数。这可以通过以下代码实现:

result = np.zeros((a.shape[1], a.shape[2]), dtype=np.int64)
result[np.arange(a.shape[1])[:, None], np.arange(a.shape[2])] = idx
result = result.transpose()
print(result)

上述代码中,我们首先使用zeros函数创建一个值全为0、形状为(3, 4)的数组result。然后使用np.arange函数创建一个行向量和一个列向量,这样就可以得到一个二维坐标数组。我们使用这个坐标数组和idx数组的值来为result数组赋值。最后,通过对result数组执行transpose函数来得到原始数组形式的结果。

完整的代码如下所示:

import numpy as np

np.random.seed(42)
a = np.random.randint(0, 20, (5, 3, 4))
print(a)

b = a.transpose(1, 2, 0)
c = b.reshape(b.shape[0], -1)
idx = c.argmax(axis=1).reshape((b.shape[0], b.shape[1]))
result = np.zeros((a.shape[1], a.shape[2]), dtype=np.int64)
result[np.arange(a.shape[1])[:, None], np.arange(a.shape[2])] = idx
result = result.transpose()
print(result)

总结

本文介绍了如何使用Numpy在多个轴上执行argmax操作,并且不需要使用循环。我们需要使用transposereshape函数来改变数组的维度。通过这种方式,我们可以获取到我们想要的结果,而且比使用循环更加高效。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程