如何将列表元素匹配至含列表的DataFrame列并返回匹配行
筛选DataFrame中列列表与指定列表存在交集的行
问题重现
给定如下DataFrame(列x存储字符串列表):
index x 0 [apple, orange, strawberry] 1 [blueberry, pear, watermelon] 2 [apple, banana, strawberry] 3 [apple] 4 [strawberry]
指定匹配列表 a = ['apple', 'strawberry'],期望筛选出列x的列表与a存在任一共同元素的行(即索引0、2、3、4的行)。但使用df[df['x'].isin(a)]仅能返回索引3、4的行,无法满足需求。
原代码的核心问题:isin(a)是判断整个列表对象是否属于a,而非检查列表内部元素与a是否有交集——只有当列x的列表恰好完全等于a中的某个元素时才会被选中,这和我们需要的"任一元素匹配"逻辑不符。
解决方案
方法1:apply结合集合交集判断
通过apply遍历列中每个列表,将列表和目标列表转为集合后求交集,只要交集非空就保留该行:
new_DF = df[df['x'].apply(lambda lst: bool(set(lst) & set(a)))]
- 逻辑说明:
set(lst) & set(a)计算两个集合的交集,bool()将空集合转为False,非空集合转为True,最终筛选出True对应的行。
方法2:explode+groupby向量化筛选
对于大数据集,apply的遍历效率较低,可以用explode将列表拆分为多行,再通过分组判断是否存在匹配元素:
# 拆分列表列,标记每个元素是否在目标列表中 mask = df.explode('x')['x'].isin(a) # 按原索引分组,只要组内有一个匹配就保留该行 new_DF = df[mask.groupby(level=0).any()]
- 逻辑说明:
explode('x')把每个列表的元素拆成单独行,isin(a)标记匹配的元素,最后groupby(level=0).any()判断原索引对应的行是否有至少一个匹配元素。
结合用户输入函数的完整代码
import pandas as pd def filter_Industries(): num_of_industries = int(input('How many industries would you like to filter by?\n')) list_industries = [] for _ in range(num_of_industries): industry = input("Enter the industry:\n") list_industries.append(industry) return list_industries # 构造示例DataFrame data = { 'x': [ ['apple', 'orange', 'strawberry'], ['blueberry', 'pear', 'watermelon'], ['apple', 'banana', 'strawberry'], ['apple'], ['strawberry'] ] } df = pd.DataFrame(data) # 获取用户输入的目标列表 a = filter_Industries() # 选择任一方法执行筛选 # 方法1 new_DF = df[df['x'].apply(lambda lst: bool(set(lst) & set(a)))] # 方法2(注释掉方法1后启用) # mask = df.explode('x')['x'].isin(a) # new_DF = df[mask.groupby(level=0).any()] print(new_DF)
内容的提问来源于stack exchange,提问作者Smalik713
相关产品推荐
相关产品推荐

