Streamlit过滤pandas DataFrame时如何避免重新运行整个脚本
Streamlit下拉选择后结果消失问题解决方案
问题原因
Streamlit默认每次用户交互都会触发全脚本重新运行,st.form_submit_button的返回值calculate仅在用户刚点击提交按钮的那一次运行周期中为True,后续选择下拉框触发重跑时,calculate会重置为False,导致包裹在if calculate:块内的计算结果、下拉组件、过滤结果全部消失。之前使用@st.cache无效的核心原因是没有解决计算结果和交互状态的持久化问题。
解决方法
使用st.session_state存储计算后的DataFrame和交互状态,将下拉过滤组件移出按钮判断块,只要计算完成就持续渲染相关组件。
修正后完整代码
import streamlit as st import pandas as pd # 初始化会话状态 if "calculated_df" not in st.session_state: st.session_state["calculated_df"] = None # 定义原始数据 d = {'id': ['a', 'b', 'c'], 'data': [3, 4,6]} df = pd.DataFrame(data=d) # 侧边栏表单 with st.sidebar.form("my_form"): a = st.slider('sidebar for testing', 5, 10, 9) calculate = st.form_submit_button('Calculate') # 点击计算按钮时更新会话状态中的结果 if calculate: temp_df = df.copy() temp_df['result'] = temp_df['data'] + a st.session_state["calculated_df"] = temp_df # 只要会话状态中存在计算结果,就展示表格和过滤组件 if st.session_state["calculated_df"] is not None: st.write(st.session_state["calculated_df"]) # 下拉过滤逻辑移到这里,不受按钮状态影响 filter_val = st.selectbox('filter data', st.session_state["calculated_df"]['id'].unique()) st.write(st.session_state["calculated_df"][st.session_state["calculated_df"]['id'] == filter_val])
关键修改说明
- 新增会话状态变量
calculated_df存储计算完成的DataFrame,不会因为脚本重跑丢失数据 - 将下拉选择框和过滤逻辑从
if calculate块中移出,只要计算完成就始终渲染 - 不需要额外加缓存装饰器,会话状态本身会在用户当前访问周期内持久化存储数据
内容的提问来源于stack exchange,提问作者luigi cogliani
相关产品推荐
相关产品推荐

