numpy二维数组按行统计众数,同分返回最大值的实现方法
解决方案
你当前使用的np.bincount(row).argmax()逻辑存在的问题是:该方法会返回第一个达到最大计数值的索引,而np.bincount返回的计数数组索引是从小到大排列的,所以多个数值出现次数相同时,只会返回最小的数值,不符合「平票取最大值」的要求。
方案1:修改列表推导(易理解,适合小数组)
对每一行的计数结果,先筛选出所有达到最大计数值的索引,直接取最大索引即可:
import numpy as np 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.max(np.where(np.bincount(row) == np.bincount(row).max())[0]) for row in Nbank])
运行后输出结果为array([3, 2, 3, 3, 2, 2, 1, 1, 2, 1, 1, 3, 1]),完全符合需求。
方案2:权重偏移法(代码更简洁)
给每个计数值添加一个极小的、和索引成正比的偏移量,该偏移量不会改变计数值本身的大小排序,只会让相同计数的情况下数值更大的索引最终排序更高,直接用argmax即可得到结果:
most_f = np.array([(np.bincount(row) + np.arange(np.bincount(row).size) * 1e-12).argmax() for row in Nbank])
方案3:向量化实现(适合超大数组)
如果需要处理行数极多的数组,可使用纯numpy向量化操作避免Python层循环,大幅提升性能:
max_val = Nbank.max() # 广播统计每行各数值的出现次数 counts = (Nbank[..., None] == np.arange(max_val + 1)).sum(axis=1) # 倒序查找最大计数的第一个索引,换算得到最大数值 most_f = counts.shape[1] - 1 - np.argmax(counts[:, ::-1], axis=1)
内容的提问来源于stack exchange,提问作者Omar Zaki
相关产品推荐
相关产品推荐

