我有一个看起来像这样的数据框:
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
,所以这里我们有Minor.Patch
同时变化,我不想只给一个标签,因为这会阻碍我的分析并导致偏见。我们也有版本从 2.3.0
到 2.4.1
的情况,其中升级模式是 Major.Minor
,最后以相同的方式升级到 Major.Patch
。该数据集具有如此奇怪的约定,因为它是从真实的 api 数据中抓取的。
除此之外,我们还有
major.minor.patch
都相等的情况,并且我们有像 alpha,beta,rc,dev,pre
这样的预标识符。在这种情况下,我想根据标准 alpha < beta < rc < pre < dev
来比较它们。在这个标识符也相同的例外情况下,我想在之后比较这个数字。有1.2.6.7
形式的案例,我认为它可以与major.minor.patch.micro(这里的micro是第4个数字)属于同一类别。
预期的输出应该是这样的:
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
我解析了所有这些版本,它们是根据 PEP440 正则表达式的规范格式,但我不确定如何比较这些版本,因为正则表达式在这里不起作用,所以我有点修复。有没有人对如何解决这个问题有想法/建议?
作为起点,您可以使用(假设数据框按
commitDate
排序):
# Simple regex pattern (subset of PEP440)
pat = r'(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(?:\.(?P<micro>\d+))?'
# Extract component version
sem = df['info_version'].str.extract(pat).fillna(0).astype(int)
# Check the difference
diff = sem.diff().fillna(0).ne(0)
# Use dot product
df['label'] = diff.dot(sem.columns + '.').str.rstrip('.')
输出:
>>> df
api_spec_id info_version commitDate label
0 803 2.3.0 2019-09-12
1 803 2.4.1 2019-10-04 minor.patch
2 803 2.4.2 2019-10-07 patch
3 803 2.5.3 2019-10-08 minor.patch
4 803 2.6.1 2019-10-08 minor.patch
5 803 2.6.3 2019-11-25 patch
6 803 2.6.5 2019-12-10 patch
7 803 2.6.6 2019-12-11 patch
8 803 2.7.2 2019-12-11 minor.patch
9 803 2.8.0 2019-12-19 minor.patch
其他输出:
>>> sem
major minor patch micro
0 2 3 0 0
1 2 4 1 0
2 2 4 2 0
3 2 5 3 0
4 2 6 1 0
5 2 6 3 0
6 2 6 5 0
7 2 6 6 0
8 2 7 2 0
9 2 8 0 0
>>> diff
major minor patch micro
0 False False False False
1 False True True False
2 False False True False
3 False True True False
4 False True True False
5 False False True False
6 False False True False
7 False False True False
8 False True True False
9 False True True False
注意:暂时不解决pre-version但是可以修改regex pattern