如何筛选含列表至少一个元素的pandas DataFrame行?
如何筛选Pandas DataFrame中Class列包含指定列表至少一个元素的行
问题场景
原始DataFrame结构如下(Class列为字符串类型):
ID Class 0 2431214 16,41,9 1 2497796 14,16,18,20,24,35,41,42 2 1407550 20,21,24,25,26,27,28,3,34,35,4,8 3 472723 1,17,22 4 423046 28,30,32,34,39,4,42,8
需要筛选出Class列包含指定列表(例如l = [16, 27])中至少一个元素的行,预期结果为:
ID Class 0 2431214 16,41,9 1 2497796 14,16,18,20,24,35,41,42 2 1407550 20,21,24,25,26,27,28,3,34,35,4,8
现有方法的问题
直接使用Pandas的isin方法无法满足需求,因为它仅返回Class列值与列表元素完全一致的行。例如执行以下代码:
l = [16, 27] filtered = df.loc[df['Class'].isin(l)]
得到的结果是仅包含Class值为16或27的行:
ID Class 210 30359 16 945 46307 27 3641 81222 27 3817 77365 27 4185 89828 16
可行解决方案
方法一:正则匹配(高效简洁)
利用str.contains结合正则表达式,匹配包含目标列表中任意独立数字的行:
l = [16, 27] # 构建正则模式,\b确保匹配独立数字,避免误匹配类似160的字符串 pattern = '|'.join(rf'\b{str(num)}\b' for num in l) filtered_df = df[df['Class'].str.contains(pattern)]
方法二:集合交集检查(直观精确)
将Class列的字符串拆分为数字集合,再与目标列表的集合求交集,判断是否有重叠:
l = [16, 27] target_set = set(l) def has_matching_element(class_str): class_nums = set(map(int, class_str.split(','))) return bool(class_nums & target_set) filtered_df = df[df['Class'].apply(has_matching_element)]
方法三:拆分展开后筛选(适合后续处理)
如果需要对Class列的单个元素进行后续操作,可以先拆分列并展开,筛选后去重:
l = [16, 27] # 拆分Class列为列表并展开 expanded_df = df.assign(Class=df['Class'].str.split(',')).explode('Class') # 转换为整数类型后筛选 expanded_df['Class'] = expanded_df['Class'].astype(int) # 筛选后按ID去重,还原原始行结构 filtered_df = expanded_df[expanded_df['Class'].isin(l)].drop_duplicates('ID')
内容的提问来源于stack exchange,提问作者Johnny
相关产品推荐
相关产品推荐

