如何用numpy等库基于二维数组每行众数生成一维数组
实现方案
方案1:scipy实现(最简洁)
直接使用scipy.stats.mode按行计算众数,搭配简单的条件判断即可实现需求,性能远高于原生Python循环:
import numpy as np from scipy import stats # asLabels为输入二维数组,maxLabel为预设兜底值 modes, counts = stats.mode(asLabels, axis=1, keepdims=False) # 统计每行有多少个元素的出现次数等于最高次数 multi_mode_flag = np.apply_along_axis( lambda x: np.sum(np.bincount(x) == counts[0]) > 1, axis=1, arr=asLabels ) # 生成结果:仅单个众数时取众数,否则取maxLabel labels = np.where(multi_mode_flag, maxLabel, modes)
方案2:纯NumPy实现(无额外依赖)
如果不想引入scipy依赖,可通过numpy内置函数实现,适合标签为非负整数的场景:
import numpy as np n_rows = asLabels.shape[0] labels = np.full(n_rows, fill_value=maxLabel, dtype=asLabels.dtype) for i in range(n_rows): cnt = np.bincount(asLabels[i]) max_cnt = cnt.max() mode_candidates = np.where(cnt == max_cnt)[0] if len(mode_candidates) == 1: labels[i] = mode_candidates[0]
补充说明
- 两种方案的运行效率都远高于你原来使用标准库
multimode的实现,数据量越大性能优势越明显 - 如果标签包含负数、浮点数,纯numpy实现需要先把标签映射为非负整数再使用
bincount,这类场景更推荐用scipy方案
内容的提问来源于stack exchange,提问作者David Thielen
相关产品推荐
相关产品推荐

