在numpy2d数组行中查找最常见的值,否则返回最大值



我有一个类似的数组

Nbank = np.array([[2, 3, 1],
[1, 2, 2],
[3, 2, 1],
[3, 2, 1],
[2, 3, 2],
[2, 2, 3],
[1, 1, 3],
[2, 1, 1],
[2, 2, 3],
[1, 1, 1],
[2, 1, 1],
[2, 3, 1],
[1, 2, 1]])

我想返回一个只有一列的数组。条件是返回每行中最常用的值;如果多个值的出现次数相同,只需返回其中的最大值。

我用了这个代码

most_f = np.array([np.bincount(row).argmax() for row in Nbank])

如果多个值的出现次数相同,则返回第一个项,而不是最大值。我该如何解决这个问题?

按行降序排序后,可以使用Counter。有一个most_common会返回您想要的内容。由于它已经排序了,所以第一个元素总是最大的或最频繁的。

import numpy as np
from collections import Counter
Nbank = np.array([[2, 3, 1],
[1, 2, 2],
[3, 2, 1],
[3, 2, 1],
[2, 3, 2],
[2, 2, 3],
[1, 1, 3],
[2, 1, 1],
[2, 2, 3],
[1, 1, 1],
[2, 1, 1],
[2, 3, 1],
[1, 2, 1]])

np.array([Counter(sorted(row, reverse=True)).most_common(1)[0][0] for row in Nbank])

输出

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

我相信这会解决问题。你可能会把它写成一句话,并有一些奇特的列表理解,但我认为这不值得。

most_f = []
for n in Nbank: #iterate over elements
counts = np.bincount(n) #count the number of elements of each value
most_f.append(np.argwhere(counts == np.max(counts))[-1][0]) #append the last and highest

您可以欺骗一点并反转每一行,以使np.argmax返回与最大项目对应的最右边出现的标记:

N = np.max(arr)
>>> [N - np.argmax(np.bincount(row, minlength=N+1)[::-1]) for row in Nbank]
[3, 2, 3, 3, 2, 2, 1, 1, 2, 1, 1, 3, 1]

如果你想充分利用numpy,你可能还想避免循环,这绝对是明智的。不幸的是,np.bincount不支持2D阵列,但您可以手动执行:

N, M = arr.shape[0], np.max(arr)+1
bincount_2D = np.zeros(shape=(N, M), dtype=int)
advanced_indexing = np.repeat(np.arange(N), arr.shape[1]), arr.ravel()
np.add.at(bincount_2D, advanced_indexing, 1)
>>> bincount_2D
array([[0, 1, 1, 1],
[0, 1, 2, 0],
[0, 1, 1, 1],
[0, 1, 1, 1],
[0, 0, 2, 1],
[0, 0, 2, 1],
[0, 2, 0, 1],
[0, 2, 1, 0],
[0, 0, 2, 1],
[0, 3, 0, 0],
[0, 2, 1, 0],
[0, 1, 1, 1],
[0, 2, 1, 0]])

然后对所有行同时重复该过程:

>>> M -1 - np.argmax(bincount_2D[:,::-1], axis=1)
array([3, 2, 3, 3, 2, 2, 1, 1, 2, 1, 1, 3, 1], dtype=int64)

最新更新