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

如何通过st.session_state或on_change实现多列动态联动筛选?

Streamlit 筛选联动与提交后数据处理实现方案

核心思路

通过st.session_state维护筛选状态与可选选项,利用组件的on_change回调实现筛选器间的实时联动,同时通过按钮或表单提交触发最终的数据处理,避免频繁刷新计算。

完整代码实现(含多筛选器联动)

首先纠正原始代码中的导入错误(应为import streamlit as st),以下是适配需求的完整代码:

import streamlit as st
import pandas as pd

# 初始化Session State,保存原始数据、筛选状态与可选选项
if 'original_df' not in st.session_state:
    st.session_state.original_df = pd.DataFrame({
        'Name': ['A', 'A', 'B', 'B', 'C', 'C', 'C', 'D', 'D', 'D', 'D'],
        'Color':['red', 'blue', 'blue', 'black', 'black', 'green', 'blue', 
                 'yellow', 'white', 'green', 'purple']
    })
    # 初始化筛选器选择值
    st.session_state.name_selection = []
    st.session_state.color_selection = []
    # 初始化筛选器可选选项
    st.session_state.name_options = st.session_state.original_df['Name'].unique().tolist()
    st.session_state.color_options = st.session_state.original_df['Color'].unique().tolist()

# 定义Name筛选器变化时的回调:更新Color可选选项
def update_color_options():
    selected_names = st.session_state.names
    # 根据当前Name选择过滤数据
    filtered_df = st.session_state.original_df.copy()
    if selected_names:
        filtered_df = filtered_df[filtered_df['Name'].isin(selected_names)]
    # 更新Color的可选选项
    st.session_state.color_options = filtered_df['Color'].unique().tolist()
    # 修正Color选择值:移除不在新选项中的内容
    valid_colors = [c for c in st.session_state.color if c in st.session_state.color_options]
    st.session_state.color = valid_colors

# 定义Color筛选器变化时的回调:更新Name可选选项
def update_name_options():
    selected_colors = st.session_state.color
    # 根据当前Color选择过滤数据
    filtered_df = st.session_state.original_df.copy()
    if selected_colors:
        filtered_df = filtered_df[filtered_df['Color'].isin(selected_colors)]
    # 更新Name的可选选项
    st.session_state.name_options = filtered_df['Name'].unique().tolist()
    # 修正Name选择值:移除不在新选项中的内容
    valid_names = [n for n in st.session_state.names if n in st.session_state.name_options]
    st.session_state.names = valid_names

# 创建筛选器(分栏布局)
col1, col2 = st.columns(2)
with col1:
    st.multiselect(
        '选择名称',
        options=st.session_state.name_options,
        key='names',
        on_change=update_color_options
    )
with col2:
    st.multiselect(
        '选择颜色',
        options=st.session_state.color_options,
        key='color',
        on_change=update_name_options
    )

# 提交按钮与数据处理逻辑
if st.button('提交'):
    # 根据所有筛选条件过滤数据
    final_df = st.session_state.original_df.copy()
    if st.session_state.names:
        final_df = final_df[final_df['Name'].isin(st.session_state.names)]
    if st.session_state.color:
        final_df = final_df[final_df['Color'].isin(st.session_state.color)]
    # 展示处理结果
    st.subheader('处理结果')
    st.dataframe(final_df)

使用st.form的优化版本

如果需要更规整的页面布局,可将筛选器与提交按钮封装在st.form中,效果与上述代码一致,但结构更清晰:

# 替换上述筛选器与提交按钮部分为以下代码
with st.form('筛选表单'):
    col1, col2 = st.columns(2)
    with col1:
        st.multiselect(
            '选择名称',
            options=st.session_state.name_options,
            key='names',
            on_change=update_color_options
        )
    with col2:
        st.multiselect(
            '选择颜色',
            options=st.session_state.color_options,
            key='color',
            on_change=update_name_options
        )
    # 表单提交按钮
    submit_btn = st.form_submit_button('提交')

if submit_btn:
    # 相同的数据处理逻辑
    final_df = st.session_state.original_df.copy()
    if st.session_state.names:
        final_df = final_df[final_df['Name'].isin(st.session_state.names)]
    if st.session_state.color:
        final_df = final_df[final_df['Color'].isin(st.session_state.color)]
    st.subheader('处理结果')
    st.dataframe(final_df)

关键知识点说明

  1. st.session_state的作用:

    • 保存原始数据、筛选器的选择值与可选选项,确保页面刷新时状态不丢失。
    • 实现不同组件间的状态共享,是联动逻辑的核心载体。
  2. on_change回调的作用:

    • 当某个筛选器的选择值变化时,立即触发回调函数,更新其他筛选器的可选选项。
    • 同时修正其他筛选器的选择值,避免出现“已选值不在当前可选列表”的矛盾情况。
  3. 是否需要st.form:

    • 不是必须,但推荐使用。它可以将所有筛选组件与提交按钮整合为一个模块,页面结构更整洁。
    • 表单内的on_change回调依然会正常触发,不影响筛选联动的实时性,仅提交按钮点击时才执行数据处理逻辑。

扩展到5-6个筛选器

只需重复以下步骤即可:

  • 在st.session_state初始化时添加对应筛选器的选择值与可选选项。
  • 为每个筛选器编写对应的on_change回调函数,更新其他所有筛选器的可选选项。
  • 在数据处理逻辑中添加对应筛选条件的过滤代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 14:45:02