目录
list.sort()
参数
特点
sorted()
参数
reverse: 定义排序顺序
key: 自定义排序规则
特点
pd.Series / pd.DataFrame.sort_values()
参数
acending: 定义排序顺序
key: 自定义排序规则
inplace: 是否改变原数据
特点
特殊场景
返回排序后的原索引
列表定义不同排序顺序
sort是列表内置的排序方法。使用示例如下:
lst = [1,3,2]
lst.sort()
lst
>>> [1,2,3]
reverse: bool, default=False.
表示排序的顺序,默认False,表示从小到大排序。设定为True时表示降序排列。
lst = [0,-1,2,3]
lst.sort(reverse=True)
lst
>>> [3,2,0,-1]
sort 特点主要有两个:
1. 排序时在原列表的基础上直接变化。
2. 作为列表内置的排序方法,仅支持列表排序时调用,其他数据类型不可调用
sorted可对任何可迭代对象(list,tuple,set,dict,pd.Series,np.array等)进行排序。调用方式为:sorted(对象)。需要注意的是,使用sorted排序后输出的结果均为list列表。
使用示例如下:
# 列表排序
lst = [1,2,0,-1]
sorted(lst)
>>> [-1,0,1,2]
# 字典键值排序
d_ = {1:1,2:9,0:1}
sorted(d_)
>>> [0,1,2]
# 元组排序
tpl = tuple([1,2,0])
sorted(tpl)
>>> [0,1,2]
# 集合排序
st = {1,2,0,3}
sorted(st)
>>> [0,1,2,3]
# pd.Series排序
import pandas as pd
sr = pd.Series([0,1,2,-1])
sorted(sr)
>>> [-1,0,1,2]
# np.array排序
import numpy as np
ar = np.array([1,3,2,-1])
sorted(ar)
>>> [-1,1,2,3]
reverse: bool, default=False.
与sort中用法一致,默认为升序,reverse=True表示倒序排列。
key参数承接函数方法,实质是一种映射规则。投入后将按照key投入的方法,对要排序的元素进行映射,之后再对映射后的数值进行排序。映射函数可以是内置方法,也可以自定义。
・内置方法
lst = [0,-1,-2,9,-3,3]
sorted(lst)
>>> [-3,-2,-1,0,3,9]
# 按照绝对值排序
sorted(lst,key=abs)
>>> [0,1,2,3,3,9]
・自定义映射方式
lst = [(2,1),(1,2),(3,0)]
# 正常排序
sorted(lst)
>>> [(1,2),(2,1),(3,0)]
# 按照元组第二个元素排序
sorted(lst,key=lambda x:x[1])
>>> [(3,0),(2,1),(1,2)]
例子中的lambda函数表示将每个数组映射成其第二个元素,按照第二个元素进行排序。
1. 与sort不同,可应用于所有可迭代对象进行排序
2. 排序后输出的结果均为列表,这意味着输出结构的数据结构可能发生改变。可能有信息丢失的风险,例如对pd.Series进行排序后,输出列表中不再保留之前数值对应的索引,索引信息丢失。
对于pandas中的两个基本数据结构Series和DataFrame,可调用内置方法sort_values进行排序,输出结果为排序后的Series/DataFrame。
pd.Series排序:
import pandas as pd
sr = pd.Series([1,2,-1,0])
sr
>>>
0 1
1 2
2 -1
3 0
dtype: int64
sr.sort_values()
>>>
2 -1
3 0
0 1
1 2
dtype: int64
pd.DataFrame排序:
在对dataframe进行排序时,要求投入排序参照的字段名称,可以是单个字段,也可以是多个字段。当输入多个字段名时,以list形式投入,排序时,将按照字段投入的先后顺序进行参照排序。
>>> df = pd.DataFrame({'name':['Jack','Mark','Jessica'],'score':[90,90,89]})
>>> df
name score
0 Jack 90
1 Mark 90
2 Jessica 89
# 按照'name'排序
>>> df.sort_values('name')
name score
0 Jack 90
2 Jessica 89
1 Mark 90
# 按照score,name排序
>>> df.sort_values(['score','name'])
name score
2 Jessica 89
0 Jack 90
1 Mark 90
# 按照name,score排序
>>> df.sort_values(['name','score'])
name score
0 Jack 90
2 Jessica 89
1 Mark 90
acending: bool, default=True.
与sort/sorted不同,pandas中sort_values定义排序顺序时的参数是acending,默认为True,表示按照从小到大的正序排列。acending=False表示按倒序顺序排序。
此外,当按照多个字段排序时,ascending支持不同字段设置不同的排序顺序,按照字段顺序以列表投入。
>>> df.sort_values(['name','score'],ascending=[False,False])
name score
1 Mark 90
2 Jessica 89
0 Jack 90
sort_values同样支持自定义映射方式,将元素映射后排序。
示例:按照x-2后的绝对值排序
>>> sr = pd.Series([0,1,-1,2,-2])
>>> sr.sort_values(key=lambda x:abs(x-2))
3 2
1 1
0 0
2 -1
4 -2
dtype: int64
inplace: bool, default=False.
默认为False,当inplace=True时,将直接在原数据上进行排序,原数据变为排序后的数据。
>>> df
name score
0 Jack 90
1 Mark 90
2 Jessica 89
>>> df.sort_values(['name','score'],inplace=True)
>>> df
name score
0 Jack 90
2 Jessica 89
1 Mark 90
1. 与sort/sorted不同,控制正序/倒序排列的参数为ascending,默认True表示正序。
2. 对不同字段可以采用不同排序方式。
经常会遇到的一种场景是,需要得到排序后数值对应的原索引。如果数据为pd.Series /DataFrame,这一需求可以直接实现,因为sort_values排序后,数值的原索引仍然保留。但如果数据为列表时,则需要另外对应。转化为series后排序诚然是方法之一,下面本文将提供另外的方法解决这一问题。
考虑到sorted中的key参数承接映射方法,根据映射后的数值排序,所以我们对索引进行排序,通过映射将索引数值映射成该索引对应的数值。
>>> lst = [1,2,3,0,2,-1]
>>> sorted(range(len(lst)),key=lambda x:lst[x])
[5,3,0,1,4,2]
sort_values中,可定义不同字段采用不同排序方式,而当列表中元素为元组或列表时,想实现不同元素按照不同顺序应该如何操作呢?此时一般使用key函数,对想要倒叙排列的元素位置进行反向映射。
>>> lst = [(1,2),(1,3),(0,1)]
# 相同顺序
>>> sorted(lst)
[(0, 1), (1, 2), (1, 3)]
# 不同顺序
>>> sorted(lst,key=lambda x:(x[0],-1*x[1]))
[(0, 1), (1, 3), (1, 2)]