StreamLit 仅在每秒更改一次后才使用 st.data_editor 更新 DataFrame

streamlit only updates dataframe after every second change using st.data_editor

提问人:Abdulrahman7ossam 提问时间:11/11/2023 更新时间:11/14/2023 访问量:90

问:

我正在尝试根据用户在具有st.data_editor的不同列中所做的更改来更改列中的值,并希望在更改时实时执行此操作。但以下代码仅在 2 次更改后有效,并且仅显示初始更改。

代码通过运行streamlit run main.py

main.py

from page import page

page()

page.py

import streamlit as st
import pandas as pd


boq_df = pd.DataFrame()


def update_dataframe():
    boq_df.loc[boq_df["ANALYZE"] == False, "TYPE"] = None
    boq_df.ffill(inplace=True)


def page():
    global boq_df

    st.write("# Test")

    if st.button("Analyze", type="primary"):
        boq_df = pd.DataFrame(
            data={
                "ANALYZE": [True, False, True],
                "CAT": ["Car", "Truck", "Bike"],
                "TYPE": ["blue", False, "yellow"],
                "DESC": ["two door", "four door", "single"],
            }
        )

    if not boq_df.empty:
        boq_df = st.data_editor(boq_df, height=700, on_change=update_dataframe())

Python Pandas DataFrame 人工智能 StreamLit

评论


答:

0赞 ferdy 11/14/2023 #1

不要在 streamlit 中使用全局变量。当用户界面发生更改时,Streamlit 始终从上到下重新运行代码。请改用内置的会话状态字典。

此外,数据编辑器中的 仅在添加或删除行时有用。对于编辑,请使用 direct 的返回值。on_changedata_editor

我试图修复你的代码。

import streamlit as st
import pandas as pd


# Create a session variable
if 'boq' not in st.session_state:
    st.session_state['boq'] = pd.DataFrame()


def page():
    st.write("# Test")

    # If button is pressed, assign a pre-built dataframe to the variable.
    if st.button("Analyze", type="primary"):
        st.session_state['boq'] = pd.DataFrame(
            data={
                "ANALYZE": [True, False, True],
                "CAT": ["Car", "Truck", "Bike"],
                "TYPE": ["blue", False, "yellow"],
                "DESC": ["two door", "four door", "single"],
            }
        )

    # If variable is not empty, construct a data_editor.
    if not st.session_state['boq'].empty:
        edited_df = st.data_editor(
            st.session_state['boq'],
            height=700
        )

        # If column "ANALYZE" is set to False, set the value of
        # "TYPE" to None. Be sure to update column "TYPE" only if
        # there are changes to column "ANALYZE".
        is_equal = edited_df['ANALYZE'].equals(st.session_state['boq']['ANALYZE'])
        if not is_equal:
            edited_df.loc[edited_df["ANALYZE"] == False, "TYPE"] = None
            edited_df.ffill(inplace=True)
            st.session_state['boq'] = edited_df  # update the variable

            # Set streamlit to rerun the script from top to bottom
            # to update the data editor.
            st.rerun()

page()

enter image description here

评论

0赞 Abdulrahman7ossam 11/17/2023
感谢您的回复,这就是我需要的,但是有没有办法在不重新加载整个脚本的情况下重新加载数据帧?
0赞 ferdy 11/18/2023
不。每当状态发生变化时,streamlit 的主要指令就是从上到下重新运行代码。在这样做的过程中,他们可能会在框架中避免大量错误,从而毫无困难地促进功能的实现。