如何用NumPy计算布尔数组列间不同元素的数量?
用NumPy计算布尔数组列间不同元素数量
给定形状为(n, m)、数据类型为bool的NumPy数组A:
import numpy as np A = np.array([[ True, False, False], [ True, True, True], [False, True, True], [False, True, False]])
需要得到形状为(m, m)、数据类型为int的数组R,其中R[i, j]表示A中第i列和第j列的不同元素数量,示例结果:
array([[0, 3, 2], [3, 0, 1], [2, 1, 0]])
实现方法
方法1:广播比较直接求和
利用NumPy的广播机制,将每一列与所有列进行元素级比较,再沿行维度求和:
# 扩展维度实现列间广播比较 R = (A[:, :, None] != A[:, None, :]).sum(axis=0)
A[:, :, None]将A转换为(n, m, 1)的形状,A[:, None, :]转换为(n, 1, m)的形状- 广播后两者进行
!=比较,得到(n, m, m)的布尔数组,每个元素表示对应列位置的元素是否不同 - 沿
axis=0(行维度)求和,得到(m, m)的结果数组,即每对列的不同元素总数
方法2:转整数后用矩阵运算优化(适合大数组)
将布尔数组转为整数(True→1,False→0),利用矩阵运算推导不同元素数量:
A_int = A.astype(int) col_sums = A_int.sum(axis=0)[:, None] # 每个列的True元素数量,形状(m,1) # 推导公式:不同元素数 = 列i的True数 + 列j的True数 - 2*两列同时为True的元素数 R = col_sums + col_sums.T - 2 * A_int.T @ A_int
- 原理:两列不同的元素数 = (列i为True且列j为False的数量) + (列i为False且列j为True的数量)
- 展开后等价于
sum(A[:,i]) + sum(A[:,j]) - 2 * sum(A[:,i] & A[:,j]),通过矩阵运算可高效批量计算所有列对
两种方法都能得到符合要求的结果,方法2在处理大规模数组时性能更优。
内容的提问来源于Stack Exchange,提问作者Riccardo Bucco
相关产品推荐
相关产品推荐

