如何 pandas 对具有其中一列作为版本号的数据框进行排序?
How to pandas sort a dataframe that has one of the columns as version numbers?
我是 Python 的初学者。我正在尝试对 versions
列 -
上的数据框进行排序
print(df)
versions memory
0 10.0.0 107.07
1 10.0.0.1 110.11
2 10.0.2 110.56
3 10.0.4 116.27
4 10.1.0 116.17
5 10.1.2 113.98
6 10.1.4 113.27
7 10.2.0 103.32
8 9.9.2 112.02
9 9.9.2.3 112.28
10 9.9.4 114.45
11 9.9.4.1 114.32
使得结果数据帧为 -
versions memory
0 9.9.2 112.02
1 9.9.2.3 112.28
2 9.9.4 114.45
3 9.9.4.1 114.32
4 10.0.0 107.07
5 10.0.0.1 110.11
6 10.0.2 110.56
7 10.0.4 116.27
8 10.1.0 116.17
9 10.1.2 113.98
10 10.1.4 113.27
11 10.2.0 103.32
versions
列的数据类型是 object
。
我试过 -
df = df.sort_values('versions')
但这会使数据框保持不变。
也试过做-
from distutils.version import StrictVersion
df = sorted(df['ghost_version'], key=StrictVersion)
但在 ValueError: invalid version number '10.0.0.1'
时出错
有人可以指导吗?
谢谢
您可以创建由整数填充的元组,通过 Series.argsort
and change order by DataFrame.iloc
, last for defaut index use DataFrame.reset_index
:
获取排序值的索引
df1 = (df.iloc[df['versions'].apply(lambda x: tuple(map(int, x.split(".")))).argsort()]
.reset_index(drop=True))
或将辅助列与 DataFrame.sort_values
一起使用,最后删除列:
df['tmp'] = df['versions'].apply(lambda x: tuple(map(int, x.split("."))))
df1 = df.sort_values('tmp').drop('tmp', axis=1).reset_index(drop=True)
对于排序值的顺序也可以使用 LooseVersion
:
from distutils.version import LooseVersion
df1 = df.iloc[df['versions'].apply(LooseVersion).argsort()].reset_index(drop=True)
versions memory
0 9.9.2 112.02
1 9.9.2.3 112.28
2 9.9.4 114.45
3 9.9.4.1 114.32
4 10.0.0 107.07
5 10.0.0.1 110.11
6 10.0.2 110.56
7 10.0.4 116.27
8 10.1.0 116.17
9 10.1.2 113.98
10 10.1.4 113.27
11 10.2.0 103.32
df['nVersion'] = df['version'].apply(lambda x: float(str(x.split('.')[0]) + '.' + str(''.join(x.split('.')[1:]))))
在此之后,您可以对 nVersion
列进行排序,然后将其删除。
给出列号而不是列名
df = df.sort_values('0')
请也看看这个解决方案
使用distutils.version.LooseVersion
的一种方式:
from distutils.version import LooseVersion
df["versions"] = df["versions"].apply(LooseVersion)
new_df = df.sort_values("versions")
# new_df["version"] = new_df["verions"].astype(str)
# if you don't want to have LooseVersion objects
print(new_df)
或从 pandas => 1.1.0
开始,sort_values
可以接受 key
,类似于 sorted
,但需要矢量化可调用对象。
f = lambda x: [LooseVersion(i) for i in x]
new_df = df.sort_values("versions", key=f)
print(new_df)
如果你想要一个全新的 RangeIndex
:
new_df = new_df.reset_index(drop=True)
re-indexing后的输出:
versions memory
0 9.9.2 112.02
1 9.9.2.3 112.28
2 9.9.4 114.45
3 9.9.4.1 114.32
4 10.0.0 107.07
5 10.0.0.1 110.11
6 10.0.2 110.56
7 10.0.4 116.27
8 10.1.0 116.17
9 10.1.2 113.98
10 10.1.4 113.27
11 10.2.0 103.32
我是 Python 的初学者。我正在尝试对 versions
列 -
print(df)
versions memory
0 10.0.0 107.07
1 10.0.0.1 110.11
2 10.0.2 110.56
3 10.0.4 116.27
4 10.1.0 116.17
5 10.1.2 113.98
6 10.1.4 113.27
7 10.2.0 103.32
8 9.9.2 112.02
9 9.9.2.3 112.28
10 9.9.4 114.45
11 9.9.4.1 114.32
使得结果数据帧为 -
versions memory
0 9.9.2 112.02
1 9.9.2.3 112.28
2 9.9.4 114.45
3 9.9.4.1 114.32
4 10.0.0 107.07
5 10.0.0.1 110.11
6 10.0.2 110.56
7 10.0.4 116.27
8 10.1.0 116.17
9 10.1.2 113.98
10 10.1.4 113.27
11 10.2.0 103.32
versions
列的数据类型是 object
。
我试过 -
df = df.sort_values('versions')
但这会使数据框保持不变。
也试过做-
from distutils.version import StrictVersion
df = sorted(df['ghost_version'], key=StrictVersion)
但在 ValueError: invalid version number '10.0.0.1'
有人可以指导吗?
谢谢
您可以创建由整数填充的元组,通过 Series.argsort
and change order by DataFrame.iloc
, last for defaut index use DataFrame.reset_index
:
df1 = (df.iloc[df['versions'].apply(lambda x: tuple(map(int, x.split(".")))).argsort()]
.reset_index(drop=True))
或将辅助列与 DataFrame.sort_values
一起使用,最后删除列:
df['tmp'] = df['versions'].apply(lambda x: tuple(map(int, x.split("."))))
df1 = df.sort_values('tmp').drop('tmp', axis=1).reset_index(drop=True)
对于排序值的顺序也可以使用 LooseVersion
:
from distutils.version import LooseVersion
df1 = df.iloc[df['versions'].apply(LooseVersion).argsort()].reset_index(drop=True)
versions memory
0 9.9.2 112.02
1 9.9.2.3 112.28
2 9.9.4 114.45
3 9.9.4.1 114.32
4 10.0.0 107.07
5 10.0.0.1 110.11
6 10.0.2 110.56
7 10.0.4 116.27
8 10.1.0 116.17
9 10.1.2 113.98
10 10.1.4 113.27
11 10.2.0 103.32
df['nVersion'] = df['version'].apply(lambda x: float(str(x.split('.')[0]) + '.' + str(''.join(x.split('.')[1:]))))
在此之后,您可以对 nVersion
列进行排序,然后将其删除。
给出列号而不是列名
df = df.sort_values('0')
请也看看这个解决方案
使用distutils.version.LooseVersion
的一种方式:
from distutils.version import LooseVersion
df["versions"] = df["versions"].apply(LooseVersion)
new_df = df.sort_values("versions")
# new_df["version"] = new_df["verions"].astype(str)
# if you don't want to have LooseVersion objects
print(new_df)
或从 pandas => 1.1.0
开始,sort_values
可以接受 key
,类似于 sorted
,但需要矢量化可调用对象。
f = lambda x: [LooseVersion(i) for i in x]
new_df = df.sort_values("versions", key=f)
print(new_df)
如果你想要一个全新的 RangeIndex
:
new_df = new_df.reset_index(drop=True)
re-indexing后的输出:
versions memory
0 9.9.2 112.02
1 9.9.2.3 112.28
2 9.9.4 114.45
3 9.9.4.1 114.32
4 10.0.0 107.07
5 10.0.0.1 110.11
6 10.0.2 110.56
7 10.0.4 116.27
8 10.1.0 116.17
9 10.1.2 113.98
10 10.1.4 113.27
11 10.2.0 103.32