为何无法判断NumPy数组元素是否存在于Pandas DataFrame中?
问题分析:判断NumPy数组元素是否存在于Pandas DataFrame中的错误原因
先还原你的场景:你已经成功实现了检查DataFrame c 第一列元素是否在NumPy数组 b 中,但反过来判断 b 的元素是否在 c 时代码无法运行,先看你的问题代码:
import numpy as np import pandas as pd # 初始化数据 a = np.array([ [2.,1.,1.], [3.,4.,1.], [5.,6.,1.], [7.,8.,1.]]) c = pd.DataFrame(data=a, dtype = 'float64') b = np.array(([1, 10, 5, 2]), dtype = 'float64') # 这段代码正常运行 for i in range(len(c)): if c.iloc[i,0] in b: print ("Great") else: print ('sad') # 输出:Great sad Great sad # 这段代码无法正常运行 for i in range(len(b)): if b[i,0] in c: print ('hola') else: print ('False')
为什么这段代码会出错?我帮你拆解两个核心问题:
错误1:NumPy数组的维度使用错误
你定义的b是一维数组——虽然你写了np.array(([1, 10, 5, 2])),但外层括号只是包裹了一个列表,NumPy会自动解析成一维数组(你可以打印b.shape验证,结果是(4,),而非(4,1))。所以b[i,0]这种二维索引的写法会直接报错,正确的索引方式是b[i],或者更简洁地直接遍历b的元素。错误2:Pandas DataFrame的
in操作逻辑和你想的不一样
当你写x in c时,Pandas的判断逻辑是检查x是否是DataFrame的列名,而不是检查x是否存在于DataFrame的元素中!这和NumPy数组的in行为完全不同——数组的in是检查元素是否在数组内,但DataFrame的in是针对列名的。所以哪怕你修正了数组索引,b[i] in c也会一直返回False,因为b里的元素都不是c的列名(c的列名是0、1、2)。
正确的实现方式
根据你的需求(应该是检查b的元素是否在c的第一列,和之前的逻辑对应),给你两种高效的写法:
方法1:针对c的第一列进行判断(推荐,效率更高)
先把c的第一列转成集合(集合的元素查找是O(1),比直接遍历列快很多),再遍历b的元素:
import numpy as np import pandas as pd a = np.array([ [2.,1.,1.], [3.,4.,1.], [5.,6.,1.], [7.,8.,1.]]) c = pd.DataFrame(data=a, dtype = 'float64') b = np.array(([1, 10, 5, 2]), dtype = 'float64') # 把c的第一列转成集合 c_first_col = set(c.iloc[:, 0]) for num in b: if num in c_first_col: print('hola') else: print('False') # 输出:False False hola hola
方法2:检查元素是否在DataFrame的任意位置
如果你需要判断b的元素是否存在于c的所有元素中,可以先把DataFrame扁平化转成一维数组再转集合:
# 把整个DataFrame转成一维数组后转集合 c_all_elements = set(c.to_numpy().flatten()) for num in b: if num in c_all_elements: print('hola') else: print('False') # 输出:hola False hola hola(因为1存在于c的其他列)
总结关键坑点:
- 别混淆NumPy一维数组和二维数组的索引方式,用
b.shape可以快速查看数组维度。 - 记住Pandas DataFrame的
in操作是检查列名的,要判断元素是否存在,必须明确指定要检查的列或者把元素转成可遍历的集合/数组。
内容的提问来源于stack exchange,提问作者Andy Wang
相关产品推荐
相关产品推荐

