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

Pandas按student分组:将含A/B双等级的记录标记为‘both’的最优实现

更优的Pandas分组实现方案

针对你的需求,这里提供几种更简洁高效的实现方式,解决原代码存在的冗余、副作用问题:

方法一:直接分组聚合

通过groupby结合自定义聚合函数,一步完成判断与结果生成:

import pandas as pd

df = pd.DataFrame({'student': 'AA AA AA BB BB BB CC CC CC CC'.split(),
                   'grade': ['B', 'B', 'B', 'A', 'A', 'B', 'B', 'B', 'B', 'B']})

result = df.groupby('student')['grade'].agg(
    lambda x: 'both' if {'A', 'B'}.issubset(x.unique()) else x.unique()[0]
).reset_index()

print(result)

输出结果:

student grade
0      AA     B
1      BB   both
2      CC     B

这种方式直接在分组后处理每个学生的等级集合,逻辑清晰,且不会修改原始DataFrame,避免意外副作用。

方法二:先构建映射字典再匹配

如果需要复用学生与等级标签的映射关系,可以先生成字典再构造结果:

# 生成每个学生的唯一等级集合
grade_sets = df.groupby('student')['grade'].apply(lambda x: set(x.unique()))
# 转换为目标标签
grade_map = grade_sets.map(lambda s: 'both' if s == {'A', 'B'} else next(iter(s)))
# 转为目标DataFrame
result = grade_map.reset_index(name='grade')

原代码的可优化点

  1. 原代码依赖crosstab生成交叉表,当等级类别较多时会占用额外内存,逻辑也相对绕;
  2. 使用inplace=True修改原始数据,容易引发意外副作用,建议始终返回新的DataFrame;
  3. 最终生成的AB不符合需求的both,需要额外替换,而上面的方法可直接生成目标标签。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 05:50:48