В настоящее время я создаю приложение streamlit, которое показывает результаты ввода пользователя. Может случиться так, что пользователь случайно отправил свои результаты. Поэтому я хочу, чтобы пользователь разрешил удалять свои значения в фрейме данных. Самый похожий вариант, который я нашел, был этот Программное удаление строк в st.data_editor, которое использует функцию обратного вызова для удаления строк. К сожалению, он работает только с первой строкой фрейма данных, но удаляет весь набор данных. Кроме того, это не работает в последних строках. Вот воспроизводимый пример:
import pandas as pd
import streamlit as st
st.sidebar.header("Submit results")
# default values
st.session_state["option"] = ""
st.session_state["number"] = 1
if 'data' not in st.session_state:
data = pd.DataFrame(columns=["Track", "Result"])
st.session_state.data = data
data = st.session_state.data
def onAddRow():
row = pd.DataFrame({'Track':[st.session_state["option"]], 'Result':[st.session_state["number"]]})
st.session_state.data = pd.concat([st.session_state.data, row])
def callback():
edited_rows = st.session_state["data_editor"]["edited_rows"]
rows_to_delete = []
for idx, value in edited_rows.items():
if value["x"] is True:
rows_to_delete.append(idx)
st.session_state["data"] = (
st.session_state["data"].drop(rows_to_delete, axis=0).reset_index(drop=True)
)
with st.form('Form1'):
st.session_state["option"] = st.selectbox(
"Select the tracked you played:",
("ds Mario Kart", "Toad Harbour", "Koopa Cape"))
st.session_state["number"] = st.slider("Pick a number", 1, 12)
st.session_state["submitted1"] = st.form_submit_button('Submit 1', on_click=onAddRow)
columns = st.session_state["data"].columns
column_config = {column: st.column_config.Column(disabled=True) for column in columns}
modified_df = st.session_state["data"].copy()
modified_df["x"] = False
# Make Delete be the first column
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,
)
Выход:
Так это выглядит. Представьте, что мы хотим удалить вторую строку, мы можем нажать кнопку в первом столбце. Но это возвращает ошибку:
KeyError: '[1] not found in axis'
Я не понимаю, почему это происходит. Поэтому мне было интересно, знает ли кто-нибудь, как создать возможность удаления строк, как указано выше, даже если у вас есть опция заполнения с помощью кнопки отправки?






Сбросьте индекс данных о состоянии вашего сеанса в обратном вызове. Это поместит индекс от 0 до n. Тогда метод drop будет работать не только для индекса 0, но и для других индексов.
st.session_state["data"] = st.session_state["data"].reset_index(drop=True)
Полный код.
def callback():
edited_rows = st.session_state["data_editor"]["edited_rows"]
rows_to_delete = []
for idx, value in edited_rows.items():
if value["x"] is True:
rows_to_delete.append(idx)
st.session_state["data"] = st.session_state["data"].reset_index(drop=True) # <--- this
st.session_state["data"] = (
st.session_state["data"].drop(rows_to_delete, axis=0).reset_index(drop=True)
)