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

如何为不同行分配排名值至新列?及拆分科目分数至对应列

两个数据处理问题的解决方案

嘿,我来帮你搞定这两个日常数据整理里的常见需求,咱们一个个来拆解:

问题一:如何为不同行的排名值分配至新列?

这个需求得看你是要全局排名还是分组排名,我给你分享两种常用工具(Python pandas 和 R)的实现方式,你可以按需选择:

Python pandas 实现

假设你有一个包含person和score的数据集,想要按分数降序生成排名:

import pandas as pd

# 示例数据
df = pd.DataFrame({
    'person': ['Joe', 'Ray', 'Jenny', 'Luna'],
    'score': [85, 92, 78, 92]
})

# 1. 全局排名(支持不同排名规则)
# method可选:average(相同分数取平均)、min(相同分数取最小排名)、max(最大)、dense(连续排名)、first(按出现顺序)
df['global_rank'] = df['score'].rank(ascending=False, method='dense')

# 2. 分组排名(比如按班级分组后排名)
# 先假设数据有class列
# df['group_rank'] = df.groupby('class')['score'].rank(ascending=False, method='dense')

print(df)

R 实现

用dplyr工具包来处理:

library(dplyr)

# 示例数据
df <- data.frame(
  person = c("Joe", "Ray", "Jenny", "Luna"),
  score = c(85, 92, 78, 92)
)

# 1. 全局连续排名
df <- df %>% mutate(global_rank = dense_rank(desc(score)))

# 2. 分组排名
# df <- df %>% group_by(class) %>% mutate(group_rank = dense_rank(desc(score))) %>% ungroup()

print(df)

问题二:批量拆分科目分数至新列(高效处理多科目)

这个需求的核心是把长格式的科目-分数对转成宽格式的列,而且要自动识别所有科目,不用手动列出来,完全适配科目数量多的场景。

Python pandas 高效实现

import pandas as pd
import re

# 你的原始数据
df = pd.DataFrame({
    'person': ['Joe', 'Ray', 'Jenny'],
    'class_score': ['gram(-),phy(+),bio(++)', 'chem(+),bio(-)', 'fin(++),db(-),pre(-)']
})

# 步骤1:拆分每个class_score条目为单独行,并提取科目和分数
# 用正则匹配科目名和括号里的分数
pattern = re.compile(r'(\w+)\((.*?)\)')
# 拆分逗号分隔的条目并展开
exploded = df['class_score'].str.split(',', expand=True).stack().reset_index(level=1, drop=True).to_frame('item')
# 提取科目和分数到新列
exploded[['cls', 'score']] = exploded['item'].str.extract(pattern)
# 和原数据合并
merged = df.join(exploded).drop(columns=['class_score', 'item'])

# 步骤2:转成宽表,自动生成所有科目列
result = merged.pivot(index='person', columns='cls', values='score').reset_index()
# 去掉列名的索引,让格式更整洁
result.columns.name = None
# 合并回原始的class_score列(重命名为cls_sco)
result = result.merge(df[['person', 'class_score']], on='person').rename(columns={'class_score': 'cls_sco'})
# 调整列顺序,把person和cls_sco放在最前面
cols = ['person', 'cls_sco'] + [col for col in result.columns if col not in ['person', 'cls_sco']]
result = result[cols]

print(result)

运行后会得到你想要的输出:缺失的科目位置会自动填充NaN(对应你示例里的NA)。

R 实现(用tidyverse)

library(tidyverse)

# 原始数据
df <- tibble(
  person = c("Joe", "Ray", "Jenny"),
  class_score = c("gram(-),phy(+),bio(++)", "chem(+),bio(-)", "fin(++),db(-),pre(-)")
)

result <- df %>%
  # 拆分每个逗号分隔的条目为单独行
  separate_rows(class_score, sep = ",") %>%
  # 提取科目和分数
  extract(class_score, into = c("cls", "score"), regex = "(\\w+)\\((.*?)\\)") %>%
  # 转成宽表,自动生成所有科目列
  pivot_wider(names_from = cls, values_from = score) %>%
  # 合并回原始的class_score列
  left_join(df, by = "person") %>%
  rename(cls_sco = class_score) %>%
  # 调整列顺序
  select(person, cls_sco, everything())

print(result)

这两种方法都是向量化操作,比循环遍历快得多,不管你有几十还是上百个科目,都能自动识别并生成对应的列,完全满足高效处理的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 22:37:57