You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Streamlit带提交功能的DataFrame行删除功能实现问题

问题分析与解决

核心错误原因

  1. 索引重复问题:原代码用pd.concat添加行时未重置索引,导致st.session_state.data的索引重复(如多次提交后索引为[0,0,0...]),删除行时无法匹配正确索引,触发KeyError。
  2. SessionState初始化错误:直接赋值st.session_state["option"] = ""会在每次页面渲染时重置用户选择,导致提交内容不符合预期。
  3. 删除逻辑匹配错误: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 12:25:23