You need to enable JavaScript to run this app. 如何高效统计numpy数组列表中各元素的重复出现次数
优惠活动
大模型
产品
解决方案
定价
更多

如何高效统计numpy数组列表中各元素的重复出现次数

高效实现NumPy数组列表去重计数的方案

针对你遇到的numpy数组不可哈希,无法直接使用集合、列表count方法去重计数、暴力比对复杂度太高的问题,有两种兼顾效率和简洁性的实现方案,时间复杂度远低于O(n²)的暴力逐对比对:

方案1:NumPy原生向量化实现(最优适配场景)

这是速度最快的方案,底层基于NumPy的C层实现,没有Python层的嵌套循环,时间复杂度为O(N*M)(N为列表中的数组总个数,M为单个numpy数组的长度),比O(n²)的暴力方法快几个数量级。

实现前提

列表中所有numpy数组的形状完全一致,从你给出的排列结果结构来看,所有数组都是长度为4的一维向量,完全满足该前提。

代码实现

import numpy as np

# 1. 将列表中的一维numpy数组堆叠为二维矩阵
stacked_arrs = np.stack(permutations, axis=0)
# 2. 直接提取唯一行,同时返回每个唯一行的出现次数
unique_arrs, repeat_counts = np.unique(stacked_arrs, axis=0, return_counts=True)
# 3. 拼接为要求的元组列表格式
neat_perm = [(arr, cnt) for arr, cnt in zip(unique_arrs, repeat_counts)]

方案2:字典哈希计数(兼容任意形状数组)

如果列表中的numpy数组存在长度不一致的情况,无法堆叠为二维矩阵,可以通过将不可哈希的numpy数组转换为可哈希的元组作为字典键,实现线性时间复杂度的计数,整体时间复杂度同样为O(N*M)。

代码实现

from collections import defaultdict

count_dict = defaultdict(int)
# 遍历一次列表完成计数,无嵌套比对
for arr in permutations:
    # 将numpy数组转为元组作为可哈希的字典键,不修改原数组内容
    hashable_key = tuple(arr.tolist())
    count_dict[hashable_key] += 1

# 还原为带原numpy数组的元组列表
neat_perm = [(np.array(key), cnt) for key, cnt in count_dict.items()]

方案优劣对比

  • 两种方案都避免了逐对比对的O(n²)复杂度,哪怕列表规模到10万条以上,运行速度也不会出现明显卡顿
  • 方案1在数组同形状的场景下,运行速度远快于纯Python实现的字典计数,是优先选择
  • 方案2灵活性更高,能兼容数组形状不一致的特殊场景,同时天然保留原列表中元素的首次出现顺序

注:numpy数组作为可变对象,本身没有实现哈希接口,这就是为什么无法直接将数组丢入集合、作为字典键、使用list.count()方法的核心原因。另外,np.unique 默认会对提取出的唯一行做字典序排序,如果需要严格保留数组在原列表中第一次出现的顺序,优先使用方案2的字典计数实现(Python 3.7+的字典会自动保留键的插入顺序,和原列表遍历顺序一致)。

内容的提问来源于stack exchange,提问作者bad_chemist

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.23 15:54:04