NumPy 获取条目的每列索引,等于二维数组中每列的最大值

NumPy get indices per column of the entries which are equal to max value per column in a 2D-array

我有一个二维数组:

A = np.array([[2,3,4],
              [2,0,4],
              [1,3,7]])

我正在搜索每列的 索引 ,它表示此列的最大值 ,而不使用 for 循环

我想要的是:

max_rowIndices_perColumn = np.array([[0,1],[0,2],[2]])

我有使用的想法:

np.where(A== np.amax(A,axis=0)) 

但是和第二步一样,我想自己处理每个特定的列,我对这个想法不是很满意。

提前致谢

定义一个函数来获取列中最大值的索引:

def idxMax(col):
    _, _, inv = np.unique(-col, return_index=True, return_inverse=True)
    return np.where(inv == 0)[0].tolist()

然后生成结果为:

result = np.array([ idxMax(col) for col in A.T ], dtype=object)

对于您的源数据,结果是:

array([list([0, 1]), list([0, 2]), list([2])], dtype=object)

请注意,在一般情况下,无法保证每一列 将 return 相同数量的最大索引,所以结果数组是 一个“衣衫褴褛”的,在这种情况下 Numpy 需要传递 dtype=object

但是如果你得到一个简单的 pythonic list of lists 就足够了 (而不是 Numpy 数组),您可以将上面的代码缩小为:

result = [ idxMax(col) for col in A.T ]

在这种情况下,结果是:

[[0, 1], [0, 2], [2]]

您需要更深入地了解索引行为。

基本上,np.where returns C 顺序(逐行)的真细胞高级索引:

>>> np.where(mask)
(array([0, 0, 1, 2, 2]), array([0, 1, 0, 1, 2]))

但您需要在 Fortran order 中(逐列)像这样进行操作:

>>> np.where(mask, order='F') # not working, it doesn't support order parameter
(array([0, 1, 0, 2, 2]), array([0, 0, 1, 1, 2]))

它不起作用,但您可以改为传递 mask.T

>>> np.where(mask.T) # fix
(array([0, 0, 1, 1, 2]), array([0, 1, 0, 2, 2]))

剩下的部分是将行索引拆分成组。总之,您可以这样解决您的问题:

mask = A == np.amax(A, axis=0)
x, y = np.where(mask.T)
div_points = np.flatnonzero(np.diff(x)) + 1
np.split(y, div_points)
>>> [array([0, 1]), array([0, 2]), array([2])]