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

为何numpy.isin函数在DataFrame中返回错误结果?

为什么numpy.isin无法正确检查DataFrame对应行中数值是否存在于列表?

问题重现

先看你的测试代码:

import pandas as pd
import numpy as np

dt = pd.DataFrame({'id' : ['a', 'a', 'a', 'b', 'b'],
                   'col_a': [1,2,5,1,2],
                   'col_b': [2,2,[2,5,4],4,[1,5,6,3,2]]})

执行np.isin(dt['col_a'], dt['col_b'])得到:

array([False,  True, False, False,  True])

第三行col_a=5明明在对应行的col_b=[2,5,4]中,结果却为False;但把第三行col_a改成4后,结果就变成True——这是因为你误解了np.isin的工作逻辑。

核心原因

np.isin(a, b)的本质是:检查数组a的每个元素是否存在于数组b的所有元素构成的全局集合中,而不是逐行配对检查a[i]是否在b[i]里。

具体到你的案例:

  • dt['col_a']是数组[1,2,5,1,2]
  • dt['col_b']的元素是[2,2,[2,5,4],4,[1,5,6,3,2]],numpy会把它当成一个object类型数组,其中的元素包括标量2、2、列表[2,5,4]、标量4、列表[1,5,6,3,2]

检查5时,dt['col_b']里没有标量5,只有列表中包含5,因此np.isin返回False;改成4后,dt['col_b']里存在标量4,所以返回True。

正确的逐行检查方法

如果你需要逐行判断col_a的数值是否在对应行col_b的列表/标量中,可以用以下几种高效方法:

方法1:列表推导式(简洁高效)

result = np.array([
    x in (y if isinstance(y, (list, set)) else [y]) 
    for x, y in zip(dt['col_a'], dt['col_b'])
])

这里先把col_b的标量统一转成单元素列表,再逐行判断归属。

方法2:集合优化(针对百万行数据)

集合的in操作比列表快很多,适合处理大型数据集:

# 先把col_b的元素转成集合,标量转成单元素集合
dt['col_b_set'] = dt['col_b'].apply(lambda x: set(x) if isinstance(x, list) else {x})
# 逐行检查
result = np.array([x in y for x, y in zip(dt['col_a'], dt['col_b_set'])])

方法3:pandas apply

def check_match(row):
    val = row['col_a']
    target = row['col_b']
    if isinstance(target, (list, set)):
        return val in target
    else:
        return val == target

result = dt.apply(check_match, axis=1).values

验证结果

用上述方法处理你的测试数据,会得到正确结果:

array([False,  True,  True, False,  True])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 08:01:27