我有一个数据框,其中的一列是带有软件名称和不同版本的字符串。尝试按此列排序时,排序不遵循版本控制。
要排序的列具有这种格式
>>> 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
答案 0 :(得分:1)
这是一个复杂的问题,因为熊猫不直接支持自然排序。幸运的是,使用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