重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
最简单的办法就是需要指定列表排序方法中的参数“key”。代码如下:
专注于为中小企业提供成都做网站、成都网站建设、成都外贸网站建设服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业沙洋免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了1000+企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。
第一种:
stu=[['john',79],['mame',96],['herry',85],['lili',95],['ziling',63]]
def takeSecond(elem):
return elem[1]
stu.sort(key=takeSecond,,reverse=True)
print(stu)
第二种:
stu=[['john',79],['mame',96],['herry',85],['lili',95],['ziling',63]]
s=sorted(stu,key=lambda student: student[1],,reverse=True)
print(s)
将Excel中的的数据读入数据框架DataFrame后,可以非常方便的进行各种数据处理。
21.1 列间求和
求总分(总分=语文+数学+英语)
对于上一章所提到的学生成绩表,仅用一个语句即可完成总分计算,并填充。
df['总分']=df['语文']+df['数学']+df['英语']
完整代码如下:
from pandas import read_excel
file='d:/student.xlsx' #见第18章表18-1
df=read_excel(file,sheet_name=0,converters={'学号':str})
df['总分']=df['语文']+df['数学']+df['英语']
print(df.head()) #df.head()的作用是仅显示5行记录。
运行结果如下:
序号 学号 姓名 年级 班级 语文 数学 英语 总分 名次
0 1 070101 王博宇 NaN NaN 84 71 93 248 NaN
1 2 070102 陈冠涛 NaN NaN 89 89 89 267 NaN
2 3 070103 李文博 NaN NaN 89 72 76 237 NaN
3 4 070204 姜海燕 NaN NaN 89 89 89 267 NaN
4 5 070205 林若溪 NaN NaN 91 95 83 269 NaN
21.2替换
既可以将对满足条件的行和列的数据替换,也可以对整个集合的数据按照条件进行替换。
df['总分'].replace(310,'x',inplace=True)
将总分列的数值“310”替换为“x”。inplace=True表示改变原数据。
df.replace(76,0,inplace=True)
将整个DataFrame中的数值“76”替换为“0”。
df.replace([98,76,99],0,inplace=True)
将整个DataFrame中的数值“98,76,99”一次替换为“0”。
21.2排序
既可以将某一列作为关键字段排序,也可以将几个列分别作为主、次关键字段进行排序。排序既可以按升序排序,也可以按降序排序。
函数sort_values()的语法格式如下:
df.sort_values(by=[“col1”,”col2”,......,”coln”],ascending=False)
其中,coln表示列名,也可以是列名的列表;ascending表示排序方式,值为True表示升序,可以省缺,值为False表示降序。
如:
df=df.sort_values(by=['总分'],ascending=False)
表示按照“总分”从高到低排序。
df=df.sort_values(by=['总分','语文'],ascending=False)
表示按照“总分”从高到低排序,若“总分”相同,再按照“语文”成绩从高到低排序。
21.3 字段截取
函数slice()可以从某列中截取字符串。格式如下:
slice(start,stop)
其中,start表示开始位置;stop表示结束位置
例:
df['年级']=df['学号'].str.slice(0,2)
通过此语句可以截取学号字段的第1、2个字符,并赋值给年级字段。
21.4 记录抽取
可以抽取满足条件的记录。
例:抽取总分300的记录。
df[df.总分300]
抽取总分在300到310之间(包括300和310)的记录。
df[df.总分.between(306,310)]
抽取学号中包含“0803”的记录。这样可以非常方便的抽取某个班的信息。
df[df.学号.str.contains('0803',na=False)]
此处的na=False,含义是如遇到NaN这样的数据,直接做不匹配处理。
21.5修改记录
1、整列替换
我们在前面已经给整列填充过数据,填充时原来的数据就被覆盖了。
即如下语句:
df['总分']=df['语文']+df['数学']+df['英语']
2、个别修改
如将值‘99’替换为值‘100’,可用如下语句:
df.replace('99','100')
将指定列的值替,如将语文列和英语列的值‘99’替换为值‘100’,可用如下语句:
df.replace({'语文':99,'英语':99},100)
可用如下程序去验证:
from pandas import read_excel
file='d:/student.xlsx'
df=read_excel(file,sheet_name=0,converters={'学号':str})
print(df[(df.语文==99) |(df.英语==99)])
df=df.replace({'语文':99,'英语':99},100)
print(df[(df.语文==99) |(df.英语==99)])
运行结果为:
序号 学号 姓名 年级 班级 语文 数学 英语 总分 名次
28 29 090802 丁能通 09 NaN 119 120 99 338 NaN
29 30 090203 沈丹妮 09 NaN 109 108 99 316 NaN
Empty DataFrame
Columns: [序号, 学号, 姓名, 年级, 班级, 语文, 数学, 英语, 总分, 名次]
Index: []
可以看出,第一个print()语句输出的结果中满足条件“语文或英语为99分”的有两条记录,替换语句执行以后,df中再没有满足条件“语文或英语为99分”的记录了。
21.6记录合并
函数concat()的格式如下:
concat([dataFrame1,dataFrame2,......],ignore_index=True)
其中,dataFrame1等表示要合并的DataFrame数据集合;ignore_index=True表示合并之后的重新建立索引。其返回值也是DataFrame类型。
concat()函数和append()函数的功能非常相似。
例:
import pandas #导入pandas模块
from pandas import read_excel #导入read_execel
file='d:/student.xlsx' #变量file表示文件路径,注意'/'的用法 数据见第18章表18-1
df=read_excel(file,sheet_name=0,converters={'学号':str})
# 将Excel文件导入到DataFrame变量中
df=df[:5] #截取df的前5个记录
print(df) #输出df
df1=df[:3] #截取df的前3个记录存入df1中
df2=df[3:5] #截取df的最后2个记录存入df2中
df3=pandas.concat([df2,df1]) #将df2与df1合并存入df3中
print(df3) #输出df3
运行结果如下:
序号 学号 姓名 年级 班级 语文 数学 英语 总分 名次
0 1 070101 王博宇 NaN NaN 84 71 93 NaN NaN
1 2 070102 陈冠涛 NaN NaN 89 89 89 NaN NaN
2 3 070103 李文博 NaN NaN 89 72 76 NaN NaN
3 4 070204 姜海燕 NaN NaN 89 89 89 NaN NaN
4 5 070205 林若溪 NaN NaN 91 95 83 NaN NaN
序号 学号 姓名 年级 班级 语文 数学 英语 总分 名次
3 4 070204 姜海燕 NaN NaN 89 89 89 NaN NaN
4 5 070205 林若溪 NaN NaN 91 95 83 NaN NaN
0 1 070101 王博宇 NaN NaN 84 71 93 NaN NaN
1 2 070102 陈冠涛 NaN NaN 89 89 89 NaN NaN
2 3 070103 李文博 NaN NaN 89 72 76 NaN NaN
由于合并时是将df1合并到df2中,可以看出,索引仍然保持原来的状态。
21.7统计次数
可以用如下方法统计出某个值在某行或者某个范围出现的次数。
from pandas import read_excel
file='d:/student.xlsx'
df=read_excel(file,sheet_name=0,converters={'学号':str})
df=df[:5]
print(df)
print(df['语文'].value_counts())
输出结果如下:
序号 学号 姓名 年级 班级 语文 数学 英语 总分 名次
0 1 070101 王博宇 NaN NaN 84 71 93 NaN NaN
1 2 070102 陈冠涛 NaN NaN 89 89 89 NaN NaN
2 3 070103 李文博 NaN NaN 89 72 76 NaN NaN
3 4 070204 姜海燕 NaN NaN 89 89 89 NaN NaN
4 5 070205 林若溪 NaN NaN 91 95 83 NaN NaN
89 3
84 1
91 1
Name: 语文, dtype: int64
可以看出,通过value_counts()函数可以统计出列中各值出现的次数。
value_counts()函数的参数还有 :
ascending,当ascending=True时升序排列,当ascending=False时升序排列(此时该参数可省缺);
normalize,当normalize=True时,显示的不再是各值出现的次数,而是占比。
将上例中的语句print(df['语文'].value_counts())改为:
print(df['语文'].value_counts(ascending=True,normalize=True))
则输出结果变成了:
91 0.2
84 0.2
89 0.6
Name: 语文, dtype: float64
21.8按值查找
print(df['语文'].isin([84,91]))
它的作用是查找‘语文’列中值和isin所指的列表中元素一致的记录,如果找到结果为True,否则为False。
输出结果:
0 True
1 False
2 False
3 False
4 True
Name: 语文, dtype: bool
21.9数据分区
根据某个分区标准,将数据按照所属区域进行划分,并用相应的标签表示,可以用cut()方法来实现。
语法格式如下:
cut(series, bins, right=True, labels=NULL)
其中:
series表示需要分组的数据;
bins表示分组的依据,是一个列表,其元素为划分分区的边界值,如[0,72,96,120],就是划分3个分区,即0~72、72~96、96~120,默认的是“左包右不包”;
right表示分组时右边是否闭合;
labels表示分组的自定义标签,也可以不重新定义。
下面对上述学生成绩表中的语文成绩进行分组,并增加一个新的列“语文等级”。
import pandas as pd
from pandas import read_excel #导入read_execel
file='d:/student.xlsx'
df=read_excel(file,sheet_name=0,converters={'学号':str})
df['年级']=df['学号'].str.slice(0,2)
df['班级']=df['学号'].str.slice(0,4)
df.总分=df.语文+df.数学+df.英语
bins=[0,72,96,max(df.语文)+1] #
lab=['不及格','及格','优秀']
grade=pd.cut(df.语文,bins,right=False,labels=lab)
df['语文等级']=grade
print(df.head())
print("语文成绩分等级统计结果:")
print(df['语文等级'].value_counts())
运行结果如下:
序号 学号 姓名 年级 班级 语文 数学 英语 总分 语文等级
0 1 070101 王博宇 07 0701 84 71 93 248 及格
1 2 070102 陈冠涛 07 0701 89 89 89 267 及格
2 3 070103 李文博 07 0701 89 72 76 237 及格
3 4 070204 姜海燕 07 0702 89 89 89 267 及格
4 5 070205 林若溪 07 0702 91 95 83 269 及格
语文成绩分等级统计结果:
及格 17
优秀 10
不及格 4
Name: 语文等级, dtype: int64
Python使用过程随记~
sort()函数与sorted()函数的区别:
sort是list的方法,而sorted可以对所有可迭代对象进行排序(字典,元组等);
sort方法返回的是对已经存在的列表进行操作,会改变原有列表的值;而sorted是新建一个新的list,不改变原有的值。
一.list sort()方法
语法:
key:主要是用来比较的参数,指定对象中的一个对象用来进行排序。
reserve:默认值为reserve=False升序,reserve=True降序。
无返回值,通常如下:
指定列表中的元素排序来输出:
二.sorted
语法:
iterable:可迭代对象
key:主要是用来比较的参数,指定对象中的一个对象用来进行排序。
reserve:默认值为reserve=False升序,reserve=True降序。
利用key进行倒序排序:
或者通过reserve参数,与sort()函数一致。
若列表内元素为字典/元组,还可以通过key指定来排序:
进行一个简单的升序排列直接调用sorted()函数,函数将会返回一个排序后的列表:
sorted函数不会改变原有的list,而是返回一个新的排好序的list
如果你想使用就地排序,也就是改变原list的内容,那么可以使用list.sort()的方法,这个方法的返回值是None。
另一个区别是,list.sort()方法只是list也就是列表类型的方法,只可以在列表类型上调用。而sorted方法则是可以接受任何可迭代对象。
list.sort()和sorted()函数都有一个key参数,可以用来指定一个函数来确定排序的一个优先级。比如,这个例子就是根据大小写的优先级进行排序:
key参数的值应该是一个函数,这个函数接受一个参数然后返回以一个key,这个key就被用作进行排序。这个方法很高效,因为对于每一个输入的记录只需要调用一次key函数。
一个常用的场景就是当我们需要对一个复杂对象的某些属性进行排序时:
再如:
前面我们看到的利用key-function来自定义排序,同时Python也可以通过operator库来自定义排序,而且通常这种方法更好理解并且效率更高。
operator库提供了 itemgetter(), attrgetter(), and a methodcaller()三个函数
同时还支持多层排序
list.sort()和sorted()都有一个boolean类型的reverse参数,可以用来指定升序和降序排列,默认为false,也就是升序排序,如果需要降序排列,则需将reverse参数指定为true。
排序的稳定性指,有相同key值的多个记录进行排序之后,原始的前后关系保持不变
我们可以看到python中的排序是稳定的。
我们可以利用这个稳定的特性来进行一些复杂的排序步骤,比如,我们将学生的数据先按成绩降序然后年龄升序。当排序是稳定的时候,我们可以先将年龄升序,再将成绩降序会得到相同的结果。
传统的DSU(Decorate-Sort-Undecorate)的排序方法主要有三个步骤:
因为元组是按字典序比较的,比较完grade之后,会继续比较i。
添加index的i值不是必须的,但是添加i值有以下好处:
现在python3提供了key-function,所以DSU方法已经不常用了
python2.x版本中,是利用cmp参数自定义排序。
python3.x已经将这个方法移除了,但是我们还是有必要了解一下cmp参数
cmp参数的使用方法就是指定一个函数,自定义排序的规则,和java等其他语言很类似
也可以反序排列
python3.x中可以用如下方式: