如何统计矩阵列表中各矩阵的出现次数?
这个需求很常见,尤其是在处理矩阵集合的时候——既要统计重复项,又不能破坏原矩阵的结构影响后续运算。下面给你两种实用的解决方案,都不需要展平原矩阵:
方法一:字典+嵌套元组转换
numpy数组本身是不可哈希的,没法直接作为字典的键,但我们可以把矩阵转换成嵌套元组(这是可哈希类型),用字典来手动统计次数。统计完成后,还能轻松把元组转回numpy数组,完全不影响后续算术运算:
import numpy as np # 你的矩阵列表 mat_list = [np.array([[0,1],[1,1]]), np.array([[1,0],[0,0]]), np.array([[0,1],[1,1]])] count_dict = {} for mat in mat_list: # 将二维数组转为嵌套元组,作为字典的键 key = tuple(map(tuple, mat)) # 计数:存在则加1,不存在则初始化为1 count_dict[key] = count_dict.get(key, 0) + 1 # 输出结果,同时把元组转回numpy数组 for key, count in count_dict.items(): print(f"{np.array(key)}: {count}")
运行后会输出:
[[0 1] [1 1]]: 2 [[1 0] [0 0]]: 1
方法二:用numpy内置函数高效统计
如果你的矩阵数量很多,用numpy的np.unique结合字节视图会更高效。核心思路是把每个矩阵转换成唯一的字节序列作为标识,统计完成后再转回原矩阵形状,全程不会修改原矩阵的结构:
import numpy as np mat_list = [np.array([[0,1],[1,1]]), np.array([[1,0],[0,0]]), np.array([[0,1],[1,1]])] # 把列表转成三维数组(前提是所有矩阵形状相同) arr_3d = np.stack(mat_list, axis=0) # 将每个矩阵转为字节视图,生成可比较的唯一标识 view = arr_3d.view(np.uint8).reshape(arr_3d.shape[0], -1) # 统计唯一视图和对应次数 unique_views, counts = np.unique(view, axis=0, return_counts=True) # 把字节视图转回原矩阵的形状和数据类型 unique_mats = unique_views.view(arr_3d.dtype).reshape(-1, *arr_3d.shape[1:]) # 输出结果 for mat, count in zip(unique_mats, counts): print(f"{mat}: {count}")
这个方法利用numpy的向量化操作,比手动遍历字典更快,适合大规模矩阵集合的场景。
补充:处理形状不一致的矩阵
如果你的列表里有不同形状的矩阵,先按形状分组再统计会更合理——毕竟不同形状的矩阵肯定是不同的:
import numpy as np mat_list = [np.array([[0,1],[1,1]]), np.array([[1,0]]), np.array([[0,1],[1,1]]), np.array([[1]])] # 先按矩阵形状分组 shape_groups = {} for mat in mat_list: shape = mat.shape if shape not in shape_groups: shape_groups[shape] = [] shape_groups[shape].append(mat) # 对每个形状分组分别统计 for shape, group in shape_groups.items(): print(f"\n形状 {shape} 的矩阵统计:") count_dict = {} for mat in group: key = tuple(map(tuple, mat)) count_dict[key] = count_dict.get(key, 0) + 1 for key, count in count_dict.items(): print(f"{np.array(key)}: {count}")
运行后会按形状分开输出统计结果,逻辑更清晰。
内容的提问来源于stack exchange,提问作者Clapham
相关产品推荐
相关产品推荐

