如何优雅获取Pandas DataFrame中不符合条件的单元格值?
问题场景
假设有如下DataFrame df:
0 1 0 ABC DEF 1 abc def
以及列表 ls = ['ABC', 'DEF', 'abc']
需求:检查df中的所有元素是否都存在于ls中,若存在不在ls中的元素,输出任意一个该类元素(示例中应输出'def')。
补充说明:需要获取满足条件(不在ls中)的单元格的具体值,常见的df.loc方法仅定位符合条件的行或列,无法直接定位到具体单元格,因此难以完美解决该问题。
本人尝试了以下两种实现方式,但都不够优雅,求更优解决方案:
第一种:
tmp = df.loc[(~df.isin(ls)).any(), :].iloc[0, :] print(tmp.loc[~tmp.isin(ls)].iloc[0])
第二种:
df.applymap(lambda s: exit(s) if s not in ls else None)
更优解决方案
这里提供几种简洁优雅的实现方式:
方法一:扁平化数据后筛选
把DataFrame转换成一维Series,直接筛选不在ls中的元素并取第一个:
# 筛选所有不在ls中的元素,取第一个结果 s = df.stack() missing_items = s[~s.isin(ls)] if not missing_items.empty: print(missing_items.iloc[0]) # 输出 'def' else: print("所有元素都在列表中")
方法二:用np.where定位位置取值
借助numpy的where找到第一个不符合条件的单元格位置,再提取对应值:
import numpy as np mask = ~df.isin(ls) if mask.any().any(): # 获取第一个不符合条件的单元格坐标 row_idx, col_idx = np.where(mask)[0][0], np.where(mask)[1][0] print(df.iloc[row_idx, col_idx]) # 输出 'def' else: print("所有元素都在列表中")
方法三:生成器遍历(高效终止)
用生成器逐个遍历单元格元素,找到第一个不在ls中的值就立即返回,无需遍历全部数据:
def get_first_missing(df, target_list): for row in df.values: for val in row: if val not in target_list: return val return None result = get_first_missing(df, ls) print(result if result else "所有元素都在列表中")
内容的提问来源于stack exchange,提问作者emilp
相关产品推荐
相关产品推荐

