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

Python Pandas动态列与对应值过滤DataFrame报错求助

动态列过滤Pandas DataFrame的掩码问题

想通过字典里的多列条件动态过滤Pandas DataFrame,之前用字符串拼接生成过滤条件,结果返回的是字符串而非布尔掩码,导致KeyError。原代码及报错如下:

import pandas as pd

# Create a list of dictionaries with the data for each row
data = [{'col1': 1, 'col2': 'a', 'col3': True, 'col4': 1.0},
        {'col1': 2, 'col2': 'b', 'col3': False, 'col4': 2.0},
        {'col1': 1, 'col2': 'c', 'col3': True, 'col4': 3.0},
        {'col1': 2, 'col2': 'd', 'col3': False, 'col4': 4.0},
        {'col1': 1, 'col2': 'e', 'col3': True, 'col4': 5.0}]
df = pd.DataFrame(data)

filter_dict = {'col1': 1, 'col3': True,}

def create_filter_query_for_df(filter_dict):
    query = ""
    for i, (column, values) in enumerate(filter_dict.items()):
        if i > 0:
            query += " & "
        if isinstance(values,float) or isinstance(values,int):
            query += f"(data['{column}'] == {values})"
        else:
            query += f"(data['{column}'] == '{values}')"
    return query

df[create_filter_query_for_df(filter_dict)]

执行后报错:

KeyError: "(data['col1'] == 1) & (data['col3'] == True)"

解决方案

方案1:直接生成布尔掩码(推荐)

跳过字符串拼接,直接遍历条件生成布尔Series并叠加,得到符合要求的过滤掩码:

import pandas as pd

data = [{'col1': 1, 'col2': 'a', 'col3': True, 'col4': 1.0},
        {'col1': 2, 'col2': 'b', 'col3': False, 'col4': 2.0},
        {'col1': 1, 'col2': 'c', 'col3': True, 'col4': 3.0},
        {'col1': 2, 'col2': 'd', 'col3': False, 'col4': 4.0},
        {'col1': 1, 'col2': 'e', 'col3': True, 'col4': 5.0}]
df = pd.DataFrame(data)

filter_dict = {'col1': 1, 'col3': True}

def create_filter_mask(df, filter_dict):
    # 初始化全True的掩码
    mask = pd.Series([True] * len(df))
    for col, val in filter_dict.items():
        # 逐个叠加条件
        mask &= (df[col] == val)
    return mask

filtered_df = df[create_filter_mask(df, filter_dict)]
print(filtered_df)

方案2:使用pandas的query方法

若偏好字符串形式的查询语句,可利用df.query()方法,调整字符串格式适配其语法:

def create_query_string(filter_dict):
    conditions = []
    for col, val in filter_dict.items():
        if isinstance(val, str):
            # 字符串值需加引号,避免语法错误
            conditions.append(f"{col} == '{val}'")
        elif isinstance(val, (int, float, bool)):
            # 数字、布尔值直接拼接
            conditions.append(f"{col} == {val}")
    return " & ".join(conditions)

query_str = create_query_string(filter_dict)
filtered_df = df.query(query_str)
print(filtered_df)

方案3:使用eval(不推荐)

如果一定要基于原字符串形式实现,可通过eval()将字符串转为布尔掩码,但注意:eval存在安全风险,若filter_dict来自不可信输入,禁止使用:

def create_filter_query_for_df(filter_dict):
    query = []
    for column, values in filter_dict.items():
        if isinstance(values, (float, int, bool)):
            query.append(f"(df['{column}'] == {values})")
        else:
            query.append(f"(df['{column}'] == '{values}')")
    return " & ".join(query)

mask_str = create_filter_query_for_df(filter_dict)
mask = eval(mask_str)
filtered_df = df[mask]
print(filtered_df)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 11:31:04