如何高效判断二维numpy数组的行是否存在于另一数组中?
问题描述
我有两个二维numpy数组:
a = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15]] b = [[1, 2, 3], [4, 5, 6], [13, 14, 15]]
需要找出第一个数组中的哪些行存在于第二个数组中,期望输出为:
desired_output = [1, 1, 0, 0, 1]
我尝试了以下代码:
x = a == b[:, None] row_sums = da.sum(x, axis=2) output = np.sum(np.where(row_sums == 6,1,0),axis=0)
但这段代码会生成形状为[5,3,3]的大型3D数组x。由于实际数组数据量很大,计算耗时过长,请问有什么优化该代码的思路?
优化方案
方法1:行转标量+集合匹配(最优内存效率)
将数组的每一行转换为可哈希的标量对象,利用集合的O(1)查找特性快速判断行的存在性,完全避免高维数组生成:
import numpy as np a = np.array(a) b = np.array(b) # 将每行转为连续字节块对应的标量类型 row_dtype = np.dtype((np.void, a.dtype.itemsize * a.shape[1])) a_rows = a.view(row_dtype).flatten() b_rows = b.view(row_dtype).flatten() # 构建集合后批量判断 b_set = set(b_rows) output = np.array([1 if row in b_set else 0 for row in a_rows])
该方法时间复杂度接近O(n+m),内存占用仅为原数组的极小部分,适合超大规模数据。
方法2:结构化数组+np.isin(向量化高效实现)
把二维数组转换为结构化数组,直接调用numpy内置的向量化函数np.isin完成匹配:
import numpy as np a = np.array(a) b = np.array(b) # 定义与行元素匹配的结构化数据类型 struct_dtype = np.dtype([(f'col{i}', a.dtype) for i in range(a.shape[1])]) # 转换为结构化数组并扁平化 a_struct = a.view(struct_dtype).flatten() b_struct = b.view(struct_dtype).flatten() # 生成结果数组 output = np.isin(a_struct, b_struct).astype(int)
此方法利用numpy底层优化的向量化操作,比手动广播逻辑效率更高,代码简洁易维护。
方法3:优化广播逻辑(最小改动原思路)
如果不想修改数据类型,可以优化原有的广播判断逻辑,减少不必要的计算步骤:
import numpy as np a = np.array(a) b = np.array(b) # 先逐行判断完全匹配,再聚合结果 row_matches = np.all(a[:, None] == b, axis=2) output = np.any(row_matches, axis=1).astype(int)
该方法依然会生成中间3D数组,但用np.all直接判断整行匹配,比原代码的求和+where组合更高效,适合数据规模中等的场景。
内容的提问来源于stack exchange,提问作者Ali Silberman
相关产品推荐
相关产品推荐

