为何Python中NumPy数组的in操作会返回非预期True?
为什么
np.array([1,1]) in np.identity(2)会返回True? 哈哈,这个坑我刚接触numpy的时候也踩过!你以为in是在检查整个向量是不是矩阵里的一行,但numpy的in逻辑和Python原生列表完全不一样——它根本不是在找完整的行匹配!
实际发生了什么?
当你用x in arr对numpy数组操作时,背后的逻辑是这样的:
- 先尝试把
x和arr做广播匹配(numpy的核心特性之一),让两者形状一致 - 对每个位置的元素做相等比较,得到一个布尔数组
- 把这个布尔数组扁平化(摊成一维),只要里面有一个
True,就返回True
拿你的例子拆解:
np.identity(2)是一个2x2矩阵:[[1, 0], [0, 1]]- 当你检查
np.array([1,1]) in np.identity(2)时,numpy会把[1,1]广播成和矩阵同形状的2x2数组:[[1,1], [1,1]] - 然后逐元素和原矩阵比较,得到:
[[True, False], [False, False]] - 扁平化后是
[True, False, False, False],里面有True,所以最终返回True
而你第一次测试的np.array([1,0]) in np.identity(2)返回True,只是刚好第一行完全匹配,导致比较后有一堆True,但本质还是因为存在匹配的元素位置。
那怎么正确检查向量是否是矩阵的一行?
如果你想确认某个完整向量是不是矩阵里的某一行,得换个写法:
vec = np.array([1,1]) mat = np.identity(2) # 检查是否有一行和vec完全匹配 any((mat == vec).all(axis=1)) # 返回False,符合预期
解释一下:
mat == vec会广播后逐元素比较,得到布尔矩阵.all(axis=1)会检查每一行是否所有元素都是True(也就是整行匹配)any()则是看是否存在这样的行
总结
numpy的in操作和Python列表的in逻辑天差地别:
- 列表的
in:检查整个元素是否存在于列表中 - numpy数组的
in:检查是否存在任意一个位置的元素(广播后)相等
内容的提问来源于stack exchange,提问作者Ziofil
相关产品推荐
相关产品推荐

