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

Python按课程分组并将字符串主题转为二进制列的问题

问题描述

我有一个大型CSV文件,每行对应一门学校课程,每门课程带有一个或多个以分号分隔的字符串主题标签。需要实现两个需求:

  • 将每个主题转为独立列,用1表示课程包含该主题,0表示不包含;
  • 对重复的课程进行分组合并,同一课程的所有关联主题均标记为1。

我尝试了一段Pandas代码,但所有二进制列结果都为0,现寻求正确实现方法。

示例输入表格:

school namedepartmentcourse nametopics
AA1Xfruit; vegetable
AA1Yfruit; grains
BB1Zfruit; vegetable; sweets
CC1XXfruit; poultry

期望输出表格:

school namedepartmentcourse namefruitvegetablegrainssweetspoultry
AA1X11000
AA1Y10100
BB1Z11010
CC1XX10001

现有代码:

import pandas as pd
import io

df = pd.read_csv(io.BytesIO(uploaded['topics.csv']))

x = df.pop("Final Topic").str.split(r"\s*;\s*").explode()
x = pd.crosstab(x.index, x).add_prefix("topic ")
df = pd.concat([df, x], axis=1)
解决方案

问题原因

代码出现全0结果的核心问题是列名不匹配:CSV中的主题列是topics,但代码里用了df.pop("Final Topic"),取出的是不存在的列,后续交叉表自然全为0。同时原代码也未处理重复课程的合并需求。

正确实现步骤

  1. 拆分topics列,将分号分隔的主题转为每行一个主题的格式;
  2. 基于课程的唯一标识(学校、院系、课程名)分组,生成主题的二进制标记,确保重复课程的所有主题都标记为1;
  3. 合并处理后的主题列与原数据集,得到最终结果。

完整代码

import pandas as pd
import io

# 读取CSV文件
df = pd.read_csv(io.BytesIO(uploaded['topics.csv']))

# 拆分主题列并展开为每行一个主题
split_topics = df['topics'].str.split(r'\s*;\s*', expand=True).stack().reset_index(level=1, drop=True).rename('topic')

# 合并原数据与拆分后的主题,生成二进制主题列并合并重复课程
df_with_topics = df.drop('topics', axis=1).join(split_topics)
result = df_with_topics.pivot_table(
    index=['school name', 'department', 'course name'],
    columns='topic',
    aggfunc='max',  # 用max确保同一课程的主题只要出现过就标记为1
    fill_value=0
).reset_index()

print(result)

代码说明

  • 修正了列名错误,使用CSV实际存在的topics列进行拆分;
  • stack()和reset_index将拆分后的多列主题转换为每行一个主题的格式,便于后续处理;
  • pivot_table通过指定课程的唯一标识作为索引,自动合并重复课程,aggfunc='max'保证同一课程的关联主题全部标记为1,fill_value=0填充未出现的主题;
  • reset_index()将索引列转回普通列,输出格式与示例完全匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 16:15:43