Python Streamlit - filter pandas dataframe而不重新运行整个脚本



我有以下代码:

import streamlit as st
import pandas as pd
#define data
d = {'id': ['a', 'b', 'c'], 'data': [3, 4,6]}
df = pd.DataFrame(data=d)
#create sidebar input
with st.sidebar.form("my_form"):
a = st.slider('sidebar for testing', 5, 10, 9)
calculate = st.form_submit_button('Calculate') 

if calculate:
df['result'] = df['data'] + a 
st.write(df)
#no issues up to this point. When I move the slider in 10 the output in 16 stays on the web page
########debug############
# I am trying to select an 'id' from the dropdown and use that to filter df, but when I select a value from the dropdown, 
# the script runs again and the output disappears
filter = st.selectbox('filter data', df['id'].unique())
st.write(df[df['id'] == filter])

我想使用下拉菜单来过滤Pandas数据框,以选择我感兴趣的id,但是当我使用下拉菜单时,代码会重新运行。

你知道怎么解决这个问题吗?

PS我还尝试将整个计算封闭在一个函数中并添加@st.cache装饰器,但没有成功。如果有人能告诉我怎么做,我会很感激的。

我可以通过不使用提交按钮来获得这种行为。每当有用户输入时,Streamlit都会从上到下重新运行脚本,因此表单提交也会重置。

d = {'id': ['a', 'b', 'c'], 'data': [3, 4, 6]}
df = pd.DataFrame(data=d)
a = st.slider('sidebar for testing', 5, 10, 9)
df['result'] = df['data'] + a
st.write(df)
# Now this will show the filtered row in the dataframe as you change the inputs
filter = st.selectbox('filter data', df['id'].unique())
st.write(df[df['id'] == filter])

对于更复杂的工作流,我会重构它并缓存加载的数据,但对于过滤数据框架,这应该可以工作。

Streamlit总是在每次用户提交时重新运行代码。但是,您可以使用st.session_state来解决这个问题,它允许在重新运行之间共享状态。它的api很像一个标准的python字典。

以下是st.session_state的示例:

import streamlit as st
import pandas as pd
#define data
d = {'id': ['a', 'b', 'c'], 'data': [3, 4,6]}
df = pd.DataFrame(data=d)

#create sidebar input
with st.sidebar.form("my_form"):
a = st.slider('sidebar for testing', 5, 10, 9)
calculate = st.form_submit_button('Calculate')
# Initialization
if 'button_pressed' not in st.session_state:
st.session_state['button_pressed'] = False
# Changes if calculated button is pressed  
if calculate:
st.session_state['button_pressed'] = True
# Conditional on session_state instead
if st.session_state['button_pressed']:
df['result'] = df['data'] + a
st.write(df)
#no issues up to this point. When I move the slider in 10 the output in 16 stays on the web page
########debug############
# I am trying to select an 'id' from the dropdown and use that to filter df, but when I select a value from the dropdown,
# the script runs again and the output disappears
filter = st.selectbox('filter data', df['id'].unique())
st.write(df[df['id'] == filter])