python - 对包含表示 Pandas 中软件版本的字符串的列进行排序
问题描述
我有一个数据框,其中一列是带有软件名称和不同版本的字符串。尝试按此列排序时,排序不尊重版本控制。
要排序的列具有这种格式
>>> import pandas as pd
>>> df = pd.DataFrame({'versions': ['cd-2.8.10', 'cd-3.10.3', 'cd-3.3.1', 'cd-3.10.10', 'cd-3.12.0', 'ab-5.2.1', 'cd-3.1.3', 'cd-3.5.2', 'ab-3.0.2', 'cd-3.10.1', 'cd-3.20.1', 'cd-3.11.4']})
>>> df
versions
0 cd-2.8.10
1 cd-3.10.3
2 cd-3.3.1
3 cd-3.10.10
4 cd-3.12.0
5 ab-5.2.1
6 cd-3.1.3
7 cd-3.5.2
8 ab-3.0.2
9 cd-3.10.1
10 cd-3.20.1
11 cd-3.11.4
当sort_values()
在破折号之前使用带有字符的字符串部分时,按字母顺序完美排序,但对于给定的软件,版本号排序错误,3.10.1
因为小于3.3.1
或3.10.10
小于3.10.3
>>> df.sort_values('versions')
versions
8 ab-3.0.2
5 ab-5.2.1
0 cd-2.8.10
6 cd-3.1.3
9 cd-3.10.1
3 cd-3.10.10
1 cd-3.10.3
11 cd-3.11.4
4 cd-3.12.0
10 cd-3.20.1
2 cd-3.3.1
7 cd-3.5.2
我想获得正确的版本排序
versions
8 ab-3.0.2
5 ab-5.2.1
0 cd-2.8.10
6 cd-3.1.3
2 cd-3.3.1
7 cd-3.5.2
9 cd-3.10.1
1 cd-3.10.3
3 cd-3.10.10
11 cd-3.11.4
4 cd-3.12.0
10 cd-3.20.1
解决方案
这是一个复杂的问题,因为 pandas 不直接支持自然排序。值得庆幸的是,使用该natsort
模块,这应该很容易并且还可以处理大多数版本格式。
from natsort import natsorted
df.iloc[natsorted(df.index, key=lambda x: df.loc[x, 'versions'])]
versions
8 ab-3.0.2
5 ab-5.2.1
0 cd-2.8.10
6 cd-3.1.3
2 cd-3.3.1
7 cd-3.5.2
9 cd-3.10.1
1 cd-3.10.3
3 cd-3.10.10
11 cd-3.11.4
4 cd-3.12.0
10 cd-3.20.1
这是对这些数据进行排序的另一种方法(它稍微快一些,因为我们避免了 lambda),
d = df.versions.to_dict()
df.iloc[natsorted(d, key=d.get)]
versions
8 ab-3.0.2
5 ab-5.2.1
0 cd-2.8.10
6 cd-3.1.3
2 cd-3.3.1
7 cd-3.5.2
9 cd-3.10.1
1 cd-3.10.3
3 cd-3.10.10
11 cd-3.11.4
4 cd-3.12.0
10 cd-3.20.1
推荐阅读
- google-apps-script - 电子表格 - 服务错误 - getlastcolumn
- angular - 为什么不是所有的角度包都声明为 devDependencies?
- javascript - 模式允许除逗号、双引号和斜杠以外的所有内容?
- c# - 是否需要在位标志枚举类型中包含`None = 0`?
- xslt-2.0 - 我想根据模板在输出 xml 中填充一个元素
- algorithm - 俄罗斯农民乘法算法的时间效率
- javascript - 在资源管理器中阻止默认设置不起作用
- javascript - 如果用户在一段时间内没有参与应用程序,则调用 localStorage.clear()
- java - 在不使用结构的情况下冒泡某种条件?
- rest - 如何将 React-Select 与 Rest API(远程数据)集成