关于Numpy中np.isin传入集合失效的原因及解决方法问询
为什么
np.isin传入Python集合会返回全False? 核心原因
np.isin的第二个参数(待匹配的候选值集合)要求是可迭代的序列类型(比如列表、Numpy数组),而Python集合是无序的容器对象,当你把它传给np.isin时,Numpy不会拆分集合里的元素,而是把整个集合当成一个单独的object类型元素存入临时数组。
这时候np.isin实际在做的是:检查mask中的每个元素是否等于这个集合对象本身,而不是检查元素是否属于该集合的成员——显然mask里的元素都是普通数值,不可能等于一个集合对象,所以返回全False。
举个直观的例子验证:
import numpy as np mask = np.array([1, 2, 3, 4]) my_set = {2, 3} # 传入集合的结果 print(np.isin(mask, my_set)) # 输出: [False False False False] # 看Numpy如何处理传入的集合 print(np.array(my_set)) # 输出: array({2, 3}, dtype=object)
当你把集合转成列表时,np.array(list(my_set))会生成array([2, 3]),此时np.isin会正确遍历这个数组的元素,检查mask中的值是否存在其中,自然得到预期结果。
兼顾效率的解决方案
如果你想保留集合去重+哈希查找的优势,同时让np.isin正常工作,最直接的方式是先把集合转成Numpy数组:
my_arr = np.array(list(my_set)) new_mask = np.where(np.isin(mask, my_arr), 1, 0)
如果数据量不大,也可以用Python集合的快速in操作结合Numpy的vectorize(注意:vectorize本质是循环,性能不如纯向量化操作,仅适合小规模数据):
is_in_set = np.vectorize(lambda x: x in my_set) new_mask = np.where(is_in_set(mask), 1, 0)
内容的提问来源于stack exchange,提问作者user16971617
相关产品推荐
相关产品推荐

