如何通过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)
关键知识点说明
st.session_state的作用:- 保存原始数据、筛选器的选择值与可选选项,确保页面刷新时状态不丢失。
- 实现不同组件间的状态共享,是联动逻辑的核心载体。
on_change回调的作用:- 当某个筛选器的选择值变化时,立即触发回调函数,更新其他筛选器的可选选项。
- 同时修正其他筛选器的选择值,避免出现“已选值不在当前可选列表”的矛盾情况。
是否需要
st.form:- 不是必须,但推荐使用。它可以将所有筛选组件与提交按钮整合为一个模块,页面结构更整洁。
- 表单内的
on_change回调依然会正常触发,不影响筛选联动的实时性,仅提交按钮点击时才执行数据处理逻辑。
扩展到5-6个筛选器
只需重复以下步骤即可:
- 在
st.session_state初始化时添加对应筛选器的选择值与可选选项。 - 为每个筛选器编写对应的
on_change回调函数,更新其他所有筛选器的可选选项。 - 在数据处理逻辑中添加对应筛选条件的过滤代码。
内容的提问来源于stack exchange,提问作者Regressor
相关产品推荐
相关产品推荐

