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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 15:54:04