Streamlit中如何根据用户输入用pandas删除DataFrame多列
问题根因
两个核心问题导致功能不符合预期:
- Streamlit的运行机制是每次用户触发组件交互(比如输入数字、点按钮)都会从头重跑整个脚本,你脚本里定义的普通变量、用
inplace=True修改的DataFrame都不会在多次重跑之间留存,每次重跑都会加载最原始的完整DataFrame,之前删掉的列自然会重新显示。你之前写的DeletedColumns=[]每次重跑都会被重新赋值为空列表,根本存不住历史选择的待删列。 st.number_input默认返回单个数值,df.columns[xcols]只能匹配到单个列,自然每次只能删除1列。
修复代码
用st.session_state做跨重跑的状态持久化,分别存原始DataFrame和已删除列的集合,每次用户提交要删除的列序号就更新待删集合,最终展示时从原始表中排除所有待删列即可,参考实现:
import streamlit as st import pandas as pd # 会话状态初始化,仅在应用首次加载时执行 if "raw_df" not in st.session_state: # 替换成你自己的DataFrame加载逻辑,下方为测试样例数据 st.session_state.raw_df = pd.DataFrame({ "列0": [1,2,3,4], "列1": [5,6,7,8], "列2": [9,10,11,12], "列3": [13,14,15,16] }) if "deleted_col_names" not in st.session_state: st.session_state.deleted_col_names = set() # 用集合自动去重,避免重复删除同一列 # 交互组件 col_idx = st.number_input("输入要删除的列序号(从0开始计数)", min_value=0, step=1) col1, col2 = st.columns(2) with col1: if st.button("确认删除当前序号列"): if 0 <= col_idx < len(st.session_state.raw_df.columns): target_col = st.session_state.raw_df.columns[int(col_idx)] st.session_state.deleted_col_names.add(target_col) with col2: if st.button("恢复所有已删除列"): st.session_state.deleted_col_names = set() st.rerun() # 渲染处理后的表格 final_df = st.session_state.raw_df.drop(columns=list(st.session_state.deleted_col_names)) st.dataframe(final_df)
扩展说明
- 不要直接在原始DataFrame上做
inplace修改,所有展示用的表都从存放在session_state的原始表派生,避免数据被改坏无法恢复。 - 如果需要支持一次删除多列,可以把数字输入框替换为多选组件
st.multiselect,直接让用户选择要删除的列名批量操作,比输入序号更不容易出错。 - 只要是需要跨用户交互留存的数据,都必须存在
st.session_state中,普通脚本变量会在每次重跑时重置。
运行效果参考:
内容的提问来源于stack exchange,提问作者Poptropica
相关产品推荐
相关产品推荐

