Numpy实现一维数组在二维数组各行的元素匹配计数
问题成因拆解
- 原代码核心逻辑错配:将集合元素成员统计实现为两个等长数组的逐位对位相等判断
- 广播维度错配细节:
- 原代码中
arr2[:, None]的形状为(3, 1, 5),与形状为(5,)的arr1完成广播后,比较逻辑为「arr2某行的第k位元素,是否等于arr1的第k位元素」 - 该逻辑完全没有“同一值在不同位置匹配”的能力:只要元素值和arr1对应位置的值不对齐,哪怕值本身存在于arr1中,也会被判定为不匹配
- 最终输出
[0 3 0]的对应原因:arr2第一行全为0,和arr1逐位比较全不匹配,计数为0;arr2第二行的前3个元素刚好和arr1的前3个位置对位相等,计数为3;arr2第三行的所有元素虽然有4个存在于arr1中,但和arr1同位置的值完全不对等,因此计数为0,与预期产生偏差。
- 原代码中
符合预期的实现方案
方案1:原生向量化广播实现
通过调整维度,让每个arr2的元素和arr1的所有元素做相等判断,匹配任意一个就标记为有效计数:
import numpy as np arr1 = np.array([2,15,132,135,136]) arr2 = np.array([[0,0,0,0,0], [2,15,132,307,406], [15,132,135,136,148]]) # 调整维度:arr2扩展为(3,5,1),arr1保持(5,),广播后形成(3,5,5)的比较矩阵 # 每个位置对应「arr2某行的某元素,是否等于arr1的某元素」 match_matrix = arr2[..., None] == arr1 # 沿最后一个维度判断是否存在任意匹配,再对每行的匹配数求和 s1 = match_matrix.any(axis=-1).sum(axis=1) print(s1) # 输出 [0 3 4]
方案2:调用numpy内置的成员判断接口(更简洁高效)
np.isin专门用于判断数组元素是否存在于目标集合中,不需要手动调整广播维度,在大数组场景下性能更优:
import numpy as np arr1 = np.array([2,15,132,135,136]) arr2 = np.array([[0,0,0,0,0], [2,15,132,307,406], [15,132,135,136,148]]) # 直接返回和arr2同形状的布尔矩阵,标记每个元素是否在arr1中存在 s1 = np.isin(arr2, arr1).sum(axis=1) print(s1) # 输出 [0 3 4]
内容的提问来源于stack exchange,提问作者Tommie
相关产品推荐
相关产品推荐

