关于Pandas版本: 本文基于 pandas2.1.2 编写。
关于本文内容更新: 随着pandas的stable版本更迭,本文持续更新,不断完善补充。
Pandas稳定版更新及变动内容整合专题: Pandas稳定版更新及变动迭持续更新。
DataFrame.sort_index()
方法用于沿 指定轴
对 DataFrame
排序。
轴
的概念很抓狂,可以简单理解为,是用 行索引
(index) 排序,还是用 列名
(labels) 排序。DataFrame.sort_index (*, axis=0, level=None, ascending=True, inplace=False, kind=‘quicksort’, na_position=‘last’, sort_remaining=True, ignore_index=False, key=None)
inplace=True
则在原始 DataFrame
原地排序,并返回 None
。inplace=False
则生成、并返回、新的、排序后的的 DataFrame
对象。axis:{0 or ‘index’, 1 or ‘columns’}, default 0 例1
用于指定沿哪个轴进行排序,默认 axis=0
:
0
或 index
: 纵向、用行索引(index)排序。1
或 comumns
: 横向、用列名(labels)排序。level: int or level name or list of ints or list of level names 例2
level
参数一般用于指定 多层索引、列名
中的某个级别,作为主要的排序依据。
整数层级编号
指定,也可以用 层级的名字
指定。?? 注意 :
- 如果指定了多个层级,这些层级必须在同一个轴上。(不能同时指定行索引、列名的层级)
- 多层索引、列名,在没有指定
level
参数的情况下,默认以指定轴的第 0 层的索引排序。- 如果用列表指定了多个层级,列表中第1个出现的层级,将作为主要排序参考。
ascending: bool or list-like of bools, default True 例3
ascending
参数用于指定排序方法(升序或降序),默认ascending=True
表示使用升序:
ascending=True
表示升序。ascending=False
则降序。?? 注意 :
- 如果使用了
level
参数,并且你还想以list-like of bools
的方式精准控制每个层级的升序降序方法,那么二者的元素数量必须等长,否则会引发报错:ValueError: level must have same length as ascending
level
参数 传递的成绩列表 和list-like of bools
传递的布尔值列表,二者元素是一一对应的关系。例如:df.sort_index(axis=0, level=[1,0], ascending=[False, True]) 意味着层级1是降序,层级0是升序。
inplace: bool, default False 例4
inplace
参数用于指是否在原始数据里进行修改,默认 inplace=False
:
DataFrame
原地排序,并返回 None
。DataFrame
对象。kind: {‘quicksort’, ‘mergesort’, ‘heapsort’, ‘stable’}, default ‘quicksort’ 例5
kind
参数用于指定排序算法,默认使用 'quicksort'
快速排序:
'stable'
。请注意,稳定排序通常会导致一些性能损失。?? 注意 :
kind
参数,只有在对单个层级的行索引、列名,进行排序时才会生效。
na_position: {‘first’, ‘last’}, default ‘last’ 例6
na_position
参数用于指定索引、列名中存在缺失值,这些缺失值排序后的堆放位置,默认na_position='last'
:
?? 注意 :
- 在多层索引、列名中此参数不可用。
sort_remaining: bool, default True 例7
sort_remaining
参数用于指当按照指定的层级排序后,其他同轴层级是否也进行排序。默认 sort_remaining=True
表示没指定的同轴其他层级,也会自动排序:
ignore_index: bool, default False 例8
ignore_index
参数用于指定,排序后,在结果中是否忽略原来的索引、列名内容。
ignore_index=True
,将会在排序后,舍弃掉 axis
参数指定轴上所有层级的的索引,并标记为从0到n-1的自然索引。key: callable, optional 例9
可以在排序之前,调用一个函数来处理制定轴的索引内容。
对于多层索引或多层列名,key
并没有提供选择层级的方法,调用的函数,将应用于指定轴的所有层级。
?? 相关方法
Sort Series by the index.
用值排序。
Sort Series by the value.
测试文件下载:
本文所涉及的测试文件,如有需要,可在文章顶部的绑定资源处下载。
若发现文件无法下载,应该是资源包有内容更新,正在审核,请稍后再试。或站内私信作者索要。
import pandas as pd
# 构建演示数据
data = {'B':[1, 2, 3, 4, 5], 'A':[6, 7, 8, 9, 10]}
idx = pd.Index([100, 29, 234, 1, 150], name='index')
df = pd.DataFrame(data, index=idx)
# 观察数据内容
df
# ... B A
# ... index
# ... 100 1 6
# ... 29 2 7
# ... 234 3 8
# ... 1 4 9
# ... 150 5 10
# 用行索引排序
df1 = df.sort_index() # 等效于df = df.sort_index(axis=0)
df1
# ... B A
# ... index
# ... 1 4 9
# ... 29 2 7
# ... 100 1 6
# ... 150 5 10
# ... 234 3 8
# 用列名排序
df2 = df.sort_index(axis=1)
df2
# ... A B
# ... index
# ... 100 6 1
# ... 29 7 2
# ... 234 8 3
# ... 1 9 4
# ... 150 10 5
import pandas as pd
# 构建演示数据
tuples = [
('1', 'a'), ('1', 'b'),
('3', 'b'), ('3', 'a'),
('2', 'a'), ('2', 'b')
]
index = pd.MultiIndex.from_tuples(tuples,names=['职业','种族'])
values = [[9, 20], [10, 18], [6, 23],
[7, 25], [4, 30], [3, 35]]
df = pd.DataFrame(values, columns=[['属性1','属性2'], ['攻速','攻击力']], index=index)
# 观察原始数据
df
属性1 | 属性2 | ||
---|---|---|---|
攻速 | 攻击力 | ||
职业 | 种族 | ||
1 | a | 9 | 20 |
b | 10 | 18 | |
3 | b | 6 | 23 |
a | 7 | 25 | |
2 | a | 4 | 30 |
b | 3 | 35 |
df2 = df.sort_index(axis=0, level=[1,0])
df2
B | A | |
---|---|---|
index | ||
1.0 | 4 | 9 |
29.0 | 2 | 7 |
100.0 | 1 | 6 |
NaN | 3 | 8 |
NaN | 5 | 10 |
有上面结果可以发现,在用列表同时指定了 职业、种族两个层级的情况下。
因为代表种族的层级编号1,出现在列表里的第1个位置。所以排序的结果,主要是以种族为标准进行的。
import pandas as pd
# 构建演示数据
data = {'B':[1, 2, 3, 4, 5], 'A':[6, 7, 8, 9, 10]}
idx = pd.Index([100, 29, 234, 1, 150], name='index')
df = pd.DataFrame(data, index=idx)
# 观察数据内容
df
# ... B A
# ... index
# ... 100 1 6
# ... 29 2 7
# ... 234 3 8
# ... 1 4 9
# ... 150 5 10
# 指定排序方法为降序
df1 = df.sort_index(axis=0,ascending=False)
df1
# ... B A
# ... index
# ... 234 3 8
# ... 150 5 10
# ... 100 1 6
# ... 29 2 7
# ... 1 4 9
import pandas as pd
# 构建演示数据
tuples = [
('1', 'a'), ('1', 'b'),
('3', 'b'), ('3', 'a'),
('2', 'a'), ('2', 'b')
]
index = pd.MultiIndex.from_tuples(tuples,names=['职业','种族'])
values = [[9, 20], [10, 18], [6, 23],
[7, 25], [4, 30], [3, 35]]
df = pd.DataFrame(values, columns=[['属性1','属性2'], ['攻速','攻击力']], index=index)
# 观察原始数据
df
# ... 属性1 属性2
# ... 攻速 攻击力
# ... 职业 种族
# ... 1 a 9 20
# ... b 10 18
# ... 3 b 6 23
# ... a 7 25
# ... 2 a 4 30
# ... b 3 35
# 指定排序以种族为准,并指定种族降序,职业升序
df1 = df.sort_index(axis=0, level=[1,0], ascending=[False, True])
df1
# ... 属性1 属性2
# ... 攻速 攻击力
# ... 职业 种族
# ... 1 b 10 18
# ... 2 b 3 35
# ... 3 b 6 23
# ... 1 a 9 20
# ... 2 a 4 30
# ... 3 a 7 25
# 不传递列表,只传递布尔值,同轴所有层级都是用一样的排序方法
df2 = df.sort_index(axis=0, ascending=False)
df2
# ... 属性1 属性2
# ... 攻速 攻击力
# ... 职业 种族
# ... 3 b 6 23
# ... a 7 25
# ... 2 b 3 35
# ... a 4 30
# ... 1 b 10 18
# ... a 9 20
import pandas as pd
# 构建演示数据
data = {'B':[1, 2, 3, 4, 5], 'A':[6, 7, 8, 9, 10]}
idx = pd.Index([100, 29, 234, 1, 150], name='index')
df = pd.DataFrame(data, index=idx)
# 观察数据内容
df
# ... B A
# ... index
# ... 100 1 6
# ... 29 2 7
# ... 234 3 8
# ... 1 4 9
# ... 150 5 10
# 指定排序方法为降序,并原地生效
df.sort_index(axis=0, ascending=False, inplace=True)
df
# ... B A
# ... index
# ... 234 3 8
# ... 150 5 10
# ... 100 1 6
# ... 29 2 7
# ... 1 4 9
例5:指定排序算法,注意!kind参数只有对单个层级排序时才会生效。
import pandas as pd
# 构建演示数据
tuples = [
('1', 'a'), ('1', 'b'),
('3', 'b'), ('3', 'a'),
('2', 'a'), ('2', 'b')
]
index = pd.MultiIndex.from_tuples(tuples,names=['职业','种族'])
values = [[9, 20], [10, 18], [6, 23],
[7, 25], [4, 30], [3, 35]]
df = pd.DataFrame(values, columns=[['属性1','属性2'], ['攻速','攻击力']], index=index)
# 观察原始数据
df
# ... 属性1 属性2
# ... 攻速 攻击力
# ... 职业 种族
# ... 1 a 9 20
# ... b 10 18
# ... 3 b 6 23
# ... a 7 25
# ... 2 a 4 30
# ... b 3 35
# 指定排序以种族为准,并指定种族降序,职业升序
df1 = df.sort_index(axis=0, level=1, kind='mergesort', ascending=False)
df1
# ... 属性1 属性2
# ... 攻速 攻击力
# ... 职业 种族
# ... 1 b 10 18
# ... 2 b 3 35
# ... 3 b 6 23
# ... 1 a 9 20
# ... 2 a 4 30
# ... 3 a 7 25
import pandas as pd
import numpy as np
# 构建演示数据
data = {'B':[1, 2, 3, 4, 5], 'A':[6, 7, 8, 9, 10]}
idx = pd.Index([100, 29, np.nan, 1, np.nan], name='index')
df = pd.DataFrame(data, index=idx)
# 观察数据内容
df
# ... B A
# ... index
# ... 100 1 6
# ... 29 2 7
# ... NaN 3 8
# ... 1 4 9
# ... NaN 5 10
# 排序,并指定缺失值排在最上面
df.sort_index(axis=0, na_position='first', inplace=True)
df
# ... B A
# ... index
# ... NaN 3 8
# ... NaN 5 10
# ... 1 4 9
# ... 29 2 7
# ... 100 1 6
import pandas as pd
# 构建演示数据
tuples = [
('1', 'a'), ('1', 'b'),
('3', 'b'), ('3', 'a'),
('2', 'a'), ('2', 'b')
]
index = pd.MultiIndex.from_tuples(tuples,names=['职业','种族'])
values = [[9, 20], [10, 18], [6, 23],
[7, 25], [4, 30], [3, 35]]
df = pd.DataFrame(values, columns=[['属性1','属性2'], ['攻速','攻击力']], index=index)
# 观察原始数据
df
属性1 | 属性2 | ||
---|---|---|---|
攻速 | 攻击力 | ||
职业 | 种族 | ||
1 | a | 9 | 20 |
b | 10 | 18 | |
3 | b | 6 | 23 |
a | 7 | 25 | |
2 | a | 4 | 30 |
b | 3 | 35 |
df1 = df.sort_index(axis=0, level='种族')
df1
属性1 | 属性2 | ||
---|---|---|---|
攻速 | 攻击力 | ||
职业 | 种族 | ||
1 | a | 9 | 20 |
2 | a | 4 | 30 |
3 | a | 7 | 25 |
1 | b | 10 | 18 |
2 | b | 3 | 35 |
3 | b | 6 | 23 |
由上面结果可以发现,同轴行索引层级 ‘职业’ 也尽可能的进行了排序。
df2 = df.sort_index(axis=0, level='种族', sort_remaining=False)
df2
属性1 | 属性2 | ||
---|---|---|---|
攻速 | 攻击力 | ||
职业 | 种族 | ||
1 | a | 9 | 20 |
3 | a | 7 | 25 |
2 | a | 4 | 30 |
1 | b | 10 | 18 |
3 | b | 6 | 23 |
2 | b | 3 | 35 |
由上面结果可以发现,由于 sort_remaining=False
同轴行索引层级 ‘职业’ 没有进行排序。
import pandas as pd
# 构建演示数据
tuples = [
('1', 'a'), ('1', 'b'),
('3', 'b'), ('3', 'a'),
('2', 'a'), ('2', 'b')
]
index = pd.MultiIndex.from_tuples(tuples,names=['职业','种族'])
values = [[9, 20], [10, 18], [6, 23],
[7, 25], [4, 30], [3, 35]]
df = pd.DataFrame(values, columns=[['属性1','属性2'], ['攻速','攻击力']], index=index)
# 排序
df2 = df.sort_index(axis=0, level='种族', sort_remaining=False, ignore_index=True)
df2
属性1 | 属性2 | |
---|---|---|
攻速 | 攻击力 | |
0 | 9 | 20 |
1 | 7 | 25 |
2 | 4 | 30 |
3 | 10 | 18 |
4 | 6 | 23 |
5 | 3 | 35 |
由上面结果可以发现,虽然在排序时,只指定了以’种族’这个层级为准进行排序,但是排序后,0轴上所有的行索引都消失了,被转换成从0开始的自然索引。
import pandas as pd
df = pd.DataFrame({"a": [1, 2, 3, 4]}, index=['A', 'b', 'C', 'd'])
# 排序前,小写字母变成大写
df.sort_index(key=lambda x: x.str.lower())
df
a | |
---|---|
A | 1 |
b | 2 |
C | 3 |
d | 4 |