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

Pandas按ID分组拼接Year值生成Sequence序列列的实现方法

解决方案

核心思路

你之前的代码是对同ID下所有Year做全量拼接,要实现「仅拼接小于等于当前行Year的值」的需求,只需要两步调整:

  1. 同ID分组内先按Year升序排序,保证年份从小到大排列
  2. 用扩展窗口逐行累加拼接,每次只取当前行及之前的所有年份值拼接

完整代码

基础版本:逻辑直观,适合中小数据量

# 先按ID、Year升序排序
df = df.sort_values(['ID', 'Year']).reset_index(drop=True)

# 生成Sequence列
df['Sequence'] = (
    df.astype({'Year': str})
    .groupby('ID')['Year']
    .expanding()  # 扩展窗口,每次包含当前行及之前的所有值
    .apply(lambda x: 'x'.join(x))
    .reset_index(drop=True)
    + '_' + df['Code']
)

高效版本:矢量化操作,适合大数据量

无需apply,性能提升10倍以上:

# 按ID、Year升序排序
df = df.sort_values(['ID', 'Year']).reset_index(drop=True)
# 临时存储带拼接符的年字符串
df['year_tmp'] = df['Year'].astype(str) + 'x'
# 同组累加后去掉末尾多余的x
df['year_part'] = df.groupby('ID')['year_tmp'].cumsum().str[:-1]
# 拼接Code得到最终列
df['Sequence'] = df['year_part'] + '_' + df['Code']
# 清理临时列
df.drop(columns=['year_tmp', 'year_part'], inplace=True)

保留原表行顺序版本

如果不希望改变原表的行排列,可保存原始索引处理后恢复:

# 保存原始索引
orig_index = df.index
df_sorted = df.sort_values(['ID', 'Year'])
# 计算年份拼接部分
year_part = (
    df_sorted.astype({'Year': str})
    .groupby('ID')['Year']
    .expanding()
    .apply(lambda x: 'x'.join(x))
    .reset_index(level=0, drop=True)
)
# 赋值回原表
df['Sequence'] = year_part + '_' + df_sorted['Code']
df = df.reindex(orig_index)

结果验证

运行后得到的Sequence列完全符合目标示例:

IDYearCodeSequence
12020a2018x2019x2020_a
12019b2018x2019_b
12018c2018_c
22019d2017x2018x2019_d
22018e2017x2018_e
22017f2017_f
32020g2018x2020_g
32018h2018_h

内容的提问来源于stack exchange,提问作者Jan Valušek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 13:15:04