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

无依赖包的语义版本比较与精准标记方案问询

版本分类标记解决方案需求

原始DataFrame结构

api_spec_id label    info_version   commitDate
    803            2.3.0            2019-09-12
    803            2.4.1            2019-10-04
    803            2.4.2            2019-10-07
    803            2.5.3            2019-10-08
    803            2.6.1            2019-10-08
    803            2.6.3            2019-11-25
    803            2.6.5            2019-12-10
    803            2.6.6            2019-12-11
    803            2.7.2            2019-12-11
    803            2.8.0            2019-12-19

现有工具局限与特殊需求

使用packaging.Version仅能标记单一版本段变更(如major、minor),但数据集存在以下特殊场景,需要更精准的分类:

  • 部分版本升级同时变更多个版本段(如2.5.3 → 2.6.1),单一标签会影响分析准确性
  • 存在Major.Minor与Patch同时变更的场景(如2.3.0 → 2.4.1)
  • 预发布版本处理:当major.minor.patch完全相同时,需按alpha < beta < rc < pre < dev规则比较;标识符相同时,比较后续数字
  • 四位版本(如1.2.6.7)需将第四位归为micro类别
  • 版本完全相同时标记为no change

预期输出

api_spec_id label    info_version           commitDate
    803      -              2.3.0                 2019-09-12
    803    minor.patch      2.4.1                 2019-10-04
    803    patch            2.4.2                 2019-10-07
    803    minor.patch      2.5.3                 2019-10-08
    803    minor.patch      2.6.1                 2019-10-08
    803    patch            2.6.3                 2019-11-25
    803    patch            2.6.5                 2019-12-10
    803    patch            2.6.6                 2019-12-11
    803    minor.patch      2.7.2                 2019-12-11
    803    major            2.8.0                 2019-12-19
    803    pre              2.8.0a1               2019-12-24
    803    pre              2.8.0a2               2019-12-27
    803    pre              2.9.0.dev             2021-01-03
    803    micro            2.9.0.2               2021-01-10
    803    no change        2.9.0.2               2021-01-15

解决方案建议

1. 自定义版本解析函数

基于PEP440规范扩展解析逻辑,将版本字符串转换为结构化数据:

  • 对四位版本(如2.9.0.2),拆分出major=2, minor=9, patch=0, micro=2
  • 对预发布版本(如2.8.0a1),提取预发布类型(alpha/a)和数字(1),并映射为权重值(alpha=0, beta=1, rc=2, pre=3, dev=4),方便比较

2. 逐组逐行对比版本差异

  • 按api_spec_id分组,每组内按commitDate排序,确保版本顺序符合时间线
  • 使用pandas.Series.shift()获取前一个版本,逐行对比当前版本与前版本的各字段:
    • 若major不同:标记major
    • 若major相同,minor不同:检查patch是否变化,同时变化则标记minor.patch,仅minor变化则标记minor
    • 若major+minor相同,patch不同:标记patch
    • 若前三项相同,micro不同:标记micro
    • 若前四项相同,预发布信息不同:标记pre
    • 所有字段完全相同:标记no change
    • 组内第一行版本标记为-

3. 结合packaging.Version简化基础解析

先用packaging.Version解析基础的major、minor、patch字段,再补充自定义逻辑处理四位版本的micro字段和预发布标识符的权重映射,减少重复开发。

4. 代码示例框架

import pandas as pd
from packaging import Version

# 预发布类型权重映射
PRE_RELEASE_WEIGHT = {
    'alpha': 0, 'a': 0,
    'beta': 1, 'b': 1,
    'rc': 2,
    'pre': 3,
    'dev': 4
}

def parse_version(version_str):
    """自定义版本解析,返回结构化字典"""
    try:
        ver = Version(version_str)
        parsed = {
            'major': ver.major,
            'minor': ver.minor,
            'patch': ver.micro if ver.micro is not None else 0,
            'micro': 0,
            'pre_type': None,
            'pre_num': 0,
            'pre_weight': -1
        }
        # 处理四位版本(如2.9.0.2)
        if len(version_str.split('.')) == 4:
            parts = version_str.split('.')
            parsed['patch'] = int(parts[2])
            parsed['micro'] = int(parts[3])
        # 处理预发布版本
        if ver.pre:
            pre_type, pre_num = ver.pre
            parsed['pre_type'] = pre_type
            parsed['pre_num'] = pre_num
            parsed['pre_weight'] = PRE_RELEASE_WEIGHT.get(pre_type, -1)
        return parsed
    except:
        # 处理非标准版本,可根据需求调整
        return None

def get_version_change_label(current, prev):
    """对比两个解析后的版本,返回变更标签"""
    if prev is None:
        return '-'
    # 比较major
    if current['major'] != prev['major']:
        return 'major'
    # 比较minor
    if current['minor'] != prev['minor']:
        if current['patch'] != prev['patch']:
            return 'minor.patch'
        return 'minor'
    # 比较patch
    if current['patch'] != prev['patch']:
        return 'patch'
    # 比较micro
    if current['micro'] != prev['micro']:
        return 'micro'
    # 比较预发布版本
    if current['pre_weight'] != prev['pre_weight'] or current['pre_num'] != prev['pre_num']:
        return 'pre'
    # 无变化
    return 'no change'

# 加载数据
df = pd.read_csv('your_data.csv')  # 替换为实际数据加载方式
# 解析版本
df['parsed_version'] = df['info_version'].apply(parse_version)
# 分组排序
df = df.sort_values(['api_spec_id', 'commitDate'])
# 获取前一个版本的解析结果
df['prev_parsed_version'] = df.groupby('api_spec_id')['parsed_version'].shift(1)
# 生成标签
df['label'] = df.apply(lambda row: get_version_change_label(row['parsed_version'], row['prev_parsed_version']), axis=1)
# 整理输出
df = df[['api_spec_id', 'label', 'info_version', 'commitDate']]
print(df.to_string(index=False))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 17:15:09