You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python:如何用内置方法查找ndarray中存在于另一ndarray的子数组

在NumPy中查找一个ndarray中包含于另一个ndarray的子数组

嘿,这个需求其实在NumPy里有几种实用的实现方式,我来给你一步步讲清楚:

方法一:利用view和np.in1d(高效推荐)

当你需要判断二维数组的整行是否存在于另一个二维数组时,直接用元素级比较会很麻烦。我们可以把每一行转换成一个连续的字节块视图,这样就能把整行当成单个元素来处理,再用np.in1d快速判断归属:

import numpy as np

arr1 = np.array([[1,2], [2,9], [3,7], [5,11], [32,5], [11,4], [89,3], [37,5]])
arr2 = np.array([[12,44], [2,9], [125,3], [37,5]])

# 将每行转换为字节视图,把二维行变成一维"元素"
dtype = np.dtype((np.void, arr1.dtype.itemsize * arr1.shape[1]))
view1 = arr1.view(dtype).ravel()
view2 = arr2.view(dtype).ravel()

# 生成掩码:标记arr2中哪些行存在于arr1中
mask = np.in1d(view2, view1)

# 获取结果
matching_subarrays = arr2[mask]
matching_indices = np.where(mask)[0]

print("匹配的子数组:", matching_subarrays)
print("在arr2中的索引:", matching_indices)

运行后会输出:

匹配的子数组: [[ 2  9]
 [37  5]]
在arr2中的索引: [1 3]

这个方法的优势是效率极高,尤其是当数组规模较大时,因为它基于哈希查找,时间复杂度接近O(n)。

方法二:利用广播和all/any(直观易懂)

如果你更喜欢直观的逻辑,可以用NumPy的广播机制来逐行比较:

import numpy as np

arr1 = np.array([[1,2], [2,9], [3,7], [5,11], [32,5], [11,4], [89,3], [37,5]])
arr2 = np.array([[12,44], [2,9], [125,3], [37,5]])

# 广播比较:arr2的每一行和arr1的所有行逐一对比
# (arr2[:, None] == arr1) 生成三维数组,最后一维是元素级相等判断
# all(axis=2) 判断整行是否完全相等,any(axis=1) 判断arr2的行是否在arr1中存在
matches = np.any((arr2[:, None] == arr1).all(axis=2), axis=1)

# 获取结果
matching_subarrays = arr2[matches]
matching_indices = np.where(matches)[0]

print("匹配的子数组:", matching_subarrays)
print("在arr2中的索引:", matching_indices)

这个方法逻辑清晰,容易理解,但要注意:当arr1和arr2的行数都很多时,会生成一个巨大的三维数组,内存开销会比较大,所以更适合小规模数组。

注意事项

  • 两个数组的子数组维度必须一致(比如这里都是二维数组,每行长度都是2),否则上述方法无法直接使用。
  • 如果子数组中有浮点数,要小心精度问题——因为浮点数的微小误差会导致匹配失败,这时候可能需要用np.isclose替代==进行比较。

内容的提问来源于stack exchange,提问作者Kromag

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:37:05