Python Streamlit — фильтрует фрейм данных панд без повторного запуска всего сценария

#python #pandas #streamlit

Вопрос:

У меня есть следующий код:

 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 с помощью выпадающего меню, чтобы выбрать интересующий меня идентификатор, но когда я использую выпадающий список, код повторяется.

Есть идеи, как я могу это решить?

PS Я также попытался вложить все вычисления в функцию и добавить @st.cache декоратора, но безуспешно. Я был бы признателен, если бы кто-нибудь мог показать мне, как это делается.

Ответ №1:

Я смог добиться такого поведения, не используя кнопку «Отправить». 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])
 

Для более сложных рабочих процессов я бы провел рефакторинг и кэшировал загружаемые данные, но для фильтрации вашего фрейма данных это должно сработать.

Ответ №2:

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])