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

如何用Python和Streamlit筛选含多标签tech字段的DataFrame

按技术标签筛选并展示项目DataFrame

需求说明

现有包含tech字段的DataFrame,该字段值为用“-”分隔的技术栈字符串。需将拆分后的单个技术值作为可选标签,用户选择任意标签时,展示对应包含该技术的项目(按project_title分组后的DataFrame)。

原错误代码

用户最初编写的代码无法得到预期结果(注:原代码缺失df初始化步骤,已补充):

import streamlit as st
import pandas as pd
import numpy as np

data = {
    'project_title': ['LSE', 'DCP', 'Job-detection', 'Task management & Organizer'],
    'tech': ['python-RegExp-PyQt5', 'python-RegExp', 'python-RegExp-BeautifulSoup-pandas', 'python-pandas-MS_SQL-CSS/HTML-Javascript'],
    'Role': ['Junior developer ', 'Python developer', 'Python developer', 'Tech lead']
}

# 补充原代码缺失的DataFrame初始化
df = pd.DataFrame(data)

# 将tech列拆分为多列
df[['tech1','tech2','tech3','tech4','tech5']]=df['tech'].str.split('-', expand=True)

# 提取各tech列的唯一值列表
tech1 = df["tech1"].unique().tolist()
tech2 = df["tech2"].unique().tolist()
tech3 = df["tech3"].unique().tolist()
tech4 = df["tech4"].unique().tolist()
tech5 = df["tech5"].unique().tolist()

# 合并所有技术列表并去除空值
tech_all = tech1+tech2+tech3+tech4+tech5
tech_all = list(filter(None, tech_all))

# 创建多选组件
regular_search_term = tech_all
choices = st.multiselect("选择技术标签", regular_search_term)

# 筛选逻辑错误:仅当整行所有tech列匹配选中标签时才保留
df_result_search=df[df.loc[:,"tech1":"tech5"].isin(choices)]

st.write(df_result_search)

原代码问题点

  • 筛选逻辑错误:df.loc[:,"tech1":"tech5"].isin(choices)返回布尔DataFrame,直接用于筛选时,只有某一行所有tech列都匹配选中标签才会被保留,不符合“包含任意选中技术”的需求。
  • 缺失df初始化步骤,直接运行会报错。

参考回答(翻译后)

@BeRT2me提供的代码同样无法实现按单个技术标签筛选的需求:

# 提取tech列的完整字符串作为选项(而非拆分后的单个技术)
regular_search_term = df.tech.unique().tolist()

# 单选组件:仅能选择完整tech字符串,无法选单个技术
choices = st.selectbox("选择技术栈", regular_search_term)
df.loc[df.tech.eq(choices), 'project_title']

# 多选组件:同样只能选择完整tech字符串,无法按单个技术筛选
choices = st.multiselect("选择技术栈", regular_search_term)
df.loc[df.tech.isin(choices), 'project_title']

参考回答的问题点

错误将完整的tech字符串作为选项,而非拆分后的单个技术标签,完全偏离了“按单个技术筛选项目”的需求。

正确解决方案

以下是实现需求的完整代码,核心是正确处理技术标签的拆分与筛选逻辑:

import streamlit as st
import pandas as pd

# 初始化数据
data = {
    'project_title': ['LSE', 'DCP', 'Job-detection', 'Task management & Organizer'],
    'tech': ['python-RegExp-PyQt5', 'python-RegExp', 'python-RegExp-BeautifulSoup-pandas', 'python-pandas-MS_SQL-CSS/HTML-Javascript'],
    'Role': ['Junior developer ', 'Python developer', 'Python developer', 'Tech lead']
}
df = pd.DataFrame(data)

# 拆分tech字段,收集所有唯一技术标签
all_techs = set()
for tech_str in df['tech']:
    techs = tech_str.split('-')
    all_techs.update(techs)
all_techs = sorted(all_techs)

# 创建多选组件供用户选择技术标签
selected_techs = st.multiselect("选择技术标签", all_techs)

# 筛选包含任意选中技术的项目
if selected_techs:
    def has_selected_tech(tech_str):
        techs = tech_str.split('-')
        return any(tech in selected_techs for tech in techs)
    df_filtered = df[df['tech'].apply(has_selected_tech)]
else:
    # 未选择标签时展示全部数据
    df_filtered = df

# 按project_title分组(如需聚合可替换agg操作,示例用first()保留每组首条数据)
df_grouped = df_filtered.groupby('project_title').first().reset_index()

# 展示结果
st.write("筛选后的项目数据:")
st.dataframe(df_grouped)

代码说明

  1. 收集技术标签:遍历每个项目的tech字符串,拆分后存入集合去重,得到所有单个技术标签。
  2. 多选组件:基于去重后的技术标签创建多选框,支持选择任意数量的技术。
  3. 精准筛选:通过apply和自定义函数检查项目tech字符串是否包含任意选中技术,确保符合条件的项目全部被保留。
  4. 分组展示:按project_title分组,示例使用first()保留每组首条数据,可根据需求替换为聚合函数(如agg({'Role': ', '.join})合并角色信息)。

内容的提问来源于stack exchange,提问作者DevLeb2022

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 15:54:55