如何在pandas中删除多列?Streamlit实现多列删除时仅识别首列触发KeyError
问题根因
for y in columns循环内逐列删列的时序错误:你在循环里先执行df[y].unique()读取列内容,再用inplace=True逐列删除,一旦第一个列被删掉,后续循环遍历到已删除的列名时,读取操作就会直接触发KeyError。- 逻辑顺序错位:删列操作和生成筛选器的操作混在同一个循环里,Streamlit每次交互都会全量重跑脚本,修改后的DataFrame会直接干扰后续的列读取逻辑。
- 没必要自己实现删列逻辑:Pandas原生
drop方法就支持直接传入列名列表一次性删除多列,比手动循环del更稳定。 - 组件状态冲突:原代码里所有筛选组件都用固定的
key="1",会导致Streamlit组件状态错乱。
修正后可直接运行的代码
import numpy as np import pandas as pd import streamlit as st # 初始化基础数据集 df = pd.DataFrame({ "source_number": [11199,11328,11287,32345,12342,1232,13456,123244,13456], "location": ["loc2","loc1-loc3","loc3","loc1","loc2-loc1","loc2","loc3-loc2","loc2","loc1"], "category": ["cat1","cat2","cat1","cat3","cat3","cat3","cat2","cat3","cat2"], }) # 侧边栏交互组件 columns_to_drop = st.sidebar.multiselect("Select column/s", df.columns) drop_button = st.sidebar.button("Remove") # 先执行删列逻辑,再生成后续筛选组件 if drop_button and columns_to_drop: # 直接传入多选返回的完整列名列表,一次性删除所有目标列 df = df.drop(columns=columns_to_drop) # 基于删列后的DataFrame生成筛选下拉框,每个组件用列名作为唯一key避免冲突 for y in df.columns: st.sidebar.multiselect(f'Filter {y}', df[y].unique(), key=y) # 展示最终数据 st.table(df)
补充说明
- 原自定义的
remove_columns函数如果要保留,直接传入多选返回的列表即可,无需逐列循环调用:def remove_columns(dataset, cols): # 返回删除指定列后的新数据集,避免inplace修改带来的副作用 return dataset.drop(columns=cols) - 不要在遍历DataFrame列的循环内穿插修改列的操作,循环遍历的列名集合是循环启动时的快照,中途修改列结构会直接破坏遍历稳定性。
- Streamlit的运行逻辑是每次交互触发都会全量重跑脚本,按照「初始化数据→渲染交互组件→执行业务逻辑→展示结果」的顺序写代码,就能避免时序错位导致的报错。
内容的提问来源于stack exchange,提问作者DevLeb2022
相关产品推荐
相关产品推荐

