Numpy如何无循环实现数组A各列在B列中的无序匹配计数
问题
定义两个Numpy数组A和B如下:
import numpy as np A = np.array([[5, 5, 5], [7, 8, 6]]) B = np.array([[5, 5], [6, 6], [9, 8]])
需要在不使用循环的前提下,统计数组A每一列的元素(不考虑元素顺序)在数组B所有列中的包含次数,最终得到结果数组C:
C = np.array([0, 1, 2])
匹配规则说明:
- C第一个元素为0:A第一列的元素组合(5,7)未在B的任何一列中出现
- C第二个元素为1:A第二列的元素组合(5,8)在B的第二列中存在(B列中其他元素不影响匹配,只要两个目标元素都存在就算命中)
- C第三个元素为2:A第三列的元素组合(5,6)在B的全部2列中均存在,因此计数为2
实现方法
利用numpy广播机制做全量批量比较,全程无Python层循环,执行效率高,代码如下:
# 转置后扩展维度做广播比较,依次判断元素存在、列命中、统计总数 C = ((A.T[:, None, :, None] == B.T[None, :, None, :]).any(-1).all(-1)).sum(1)
代码逻辑拆解:
- 对A、B做转置,将原数组的列转换为新数组的行,把按列匹配的需求转换为按行匹配
- 扩展维度后做相等判断,利用广播自动生成所有A列元素和B列元素的匹配矩阵
.any(-1):判断A列的单个元素是否在对应B列中存在.all(-1):判断A列的两个目标元素是否都在对应B列中存在,得到列命中的布尔矩阵.sum(1):按A列维度统计总命中次数,得到最终结果C
运行上述代码可以得到正确输出[0 1 2]。
内容的提问来源于stack exchange,提问作者Mario
相关产品推荐
相关产品推荐

