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

基于用户下拉框输入动态过滤Pandas DataFrame的技术问题

优雅解决Pandas DataFrame动态过滤问题

我完全懂你不想写一堆冗余if-else分支来覆盖所有过滤组合的心情!这里有个简洁的方法,通过动态组合布尔过滤条件实现需求——只对非"All"的选项应用过滤,自动跳过选择"All"的列。

步骤1:保留你的下拉框生成逻辑

你的unique函数和Streamlit下拉框渲染代码可以原样保留,这部分没问题:

import streamlit as st
import pandas as pd

def unique(df, col_nme, **kwargs):
    lst_nme = df[col_nme].unique().tolist()
    lst_nme.insert(0, "All")
    return lst_nme

# 假设df是你的原始DataFrame
# df = pd.read_csv("your_data.csv") 

# 渲染侧边栏下拉框
lst_rprt_status = unique(df, "Reporting Status")
rprt_status = st.sidebar.selectbox("Reporting Status", lst_rprt_status)

lst_src = unique(df, "Source")
src = st.sidebar.selectbox("Source", lst_src)

lst_cntrct_type = unique(df, "Contract Type")
cntrct_type = st.sidebar.selectbox("Contract Type", lst_cntrct_type)

lst_country = unique(df, "Country")
country = st.sidebar.selectbox("Country", lst_country)

步骤2:动态组合过滤条件

我们把列名、选择值配对成一个列表,遍历后只筛选出选择值不是"All"的条件,最后用&(逻辑与)把所有有效条件组合起来:

# 把列名和对应的选择值打包成元组列表
filter_pairs = [
    ("Reporting Status", rprt_status),
    ("Source", src),
    ("Contract Type", cntrct_type),
    ("Country", country)
]

# 初始化过滤条件为全True(即不做任何过滤)
final_filter = pd.Series([True] * len(df), index=df.index)

# 遍历每个配对,动态叠加有效过滤条件
for col_name, selected_val in filter_pairs:
    if selected_val != "All":
        final_filter &= df[col_name] == selected_val

# 应用过滤得到结果
filtered_df = df[final_filter]

为什么这个方法好用?

  • 初始的final_filter是全True的Series,相当于默认展示完整数据;
  • 每遇到非"All"的选择,就用&叠加对应布尔条件,实现多条件同时过滤;
  • 不管哪个下拉框选"All",都会自动跳过该列的过滤,完全不用写分支判断;
  • 后续要加新的下拉框,只需要在filter_pairs里加一行元组就行,扩展性超强!

额外优化:用df.query的简化写法

如果你更喜欢SQL风格的查询写法,也可以动态拼接查询字符串:

query_parts = []
for col_name, selected_val in filter_pairs:
    if selected_val != "All":
        # 针对字符串类型的值添加引号,避免语法错误
        if df[col_name].dtype == object:
            query_parts.append(f"`{col_name}` == '{selected_val}'")
        else:
            query_parts.append(f"`{col_name}` == {selected_val}")

# 用and拼接所有查询条件,无过滤条件时直接返回原df
final_query = " and ".join(query_parts)
filtered_df = df.query(final_query) if query_parts else df

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 07:43:15