Streamlit带提交功能的DataFrame行删除功能实现问题
问题分析与解决
核心错误原因
- 索引重复问题:原代码用
pd.concat添加行时未重置索引,导致st.session_state.data的索引重复(如多次提交后索引为[0,0,0...]),删除行时无法匹配正确索引,触发KeyError。 - SessionState初始化错误:直接赋值
st.session_state["option"] = ""会在每次页面渲染时重置用户选择,导致提交内容不符合预期。 - 删除逻辑匹配错误:
st.data_editor的edited_rows键对应行的显示位置(而非DataFrame索引),当索引重复时无法正确映射到原数据行。
修复后的完整代码
import pandas as pd import streamlit as st st.sidebar.header("Submit results") # 正确初始化SessionState变量:仅当变量不存在时设置默认值 if 'option' not in st.session_state: st.session_state["option"] = "" if 'number' not in st.session_state: st.session_state["number"] = 1 if 'data' not in st.session_state: st.session_state.data = pd.DataFrame(columns=["Track", "Result"]) def onAddRow(): # 添加行时使用ignore_index=True确保索引连续唯一 row = pd.DataFrame({'Track': [st.session_state["option"]], 'Result': [st.session_state["number"]]}) st.session_state.data = pd.concat([st.session_state.data, row], ignore_index=True) def callback(): edited_rows = st.session_state["data_editor"]["edited_rows"] rows_to_delete = [] # 遍历编辑行,收集需要删除的行位置 for idx, value in edited_rows.items(): if value.get("x") is True: rows_to_delete.append(idx) # 根据行位置获取原数据的索引,执行删除并重置索引 if rows_to_delete: st.session_state.data = st.session_state.data.drop(st.session_state.data.index[rows_to_delete], axis=0).reset_index(drop=True) # 清除data_editor的状态,避免残留编辑记录 st.session_state.pop("data_editor", None) with st.form('Form1'): st.session_state["option"] = st.selectbox( "Select the track you played:", ("ds Mario Kart", "Toad Harbour", "Koopa Cape")) st.session_state["number"] = st.slider("Pick a number", 1, 12) st.form_submit_button('Submit 1', on_click=onAddRow) # 配置数据编辑器的列:将x列设为复选框,标记删除 column_config = { "x": st.column_config.CheckboxColumn("Delete", help="Check to delete this row"), "Track": st.column_config.Column(disabled=True), "Result": st.column_config.Column(disabled=True) } modified_df = st.session_state.data.copy() modified_df["x"] = False # 调整列顺序,将删除复选框放在最前面 modified_df = modified_df[["x"] + modified_df.columns[:-1].tolist()] st.data_editor( modified_df, key="data_editor", on_change=callback, hide_index=True, column_config=column_config, use_container_width=True )
关键修复点说明
- SessionState初始化:用
if 'key' not in st.session_state判断,避免每次渲染重置用户输入。 - 添加行逻辑:
pd.concat时添加ignore_index=True,保证新数据的索引从0开始连续递增,避免重复。 - 删除行逻辑:通过
st.session_state.data.index[rows_to_delete]将行位置转换为原数据的实际索引,确保删除正确的行;删除后清除data_editor的状态,避免残留编辑记录导致后续错误。 - 列配置优化:将
x列设为CheckboxColumn,明确标记为删除按钮,提升用户体验。
内容的提问来源于stack exchange,提问作者Quinten
相关产品推荐
相关产品推荐

