Pandas用法总结
Pandas简介
Pandas是基于NumPy的一种工具,该工具是为了解决数据分析任务而创建的。Pandas纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据库所需的工具。Pandas提供了大量能使我们快速便捷地处理数据的函数和方法。Pandas基于两种数据类型:series 和 dataframe
Series
Series是Pandas中最基本的对象,类似一维数组。事实上,Series基本上就是基于NumPy的数组对象来的,和NumPy的数组不同,Series能为数据自定义标签,也就是索引(index),然后通过索引来访问数组中的数据。用法总结如下:
Series对象的创建
# pandas 学习
import pandas as pd
from pandas import Series,DataFrame
import numpy as np
# 一维数组
sel = Series([1,2,3,4])
# 会同时打印索引和对应的元素
print(sel)
# 但通常我们会自己创建索引 index代表索引
# sel= Series(data=[1,2,3,4],index=[\'a\',\'b\',\'c\',\'d\'])
sel = Series(data=[1,2,3,4],index=list(\'abcd\'))
print(\'数组:\')
print(sel)
# 获取内容
print(\'数组值:\',sel.values)
# 获取索引
print(\'数组下标\',sel.index)
# 同时获取索引和值
print(\'同时获取索引和对应值\',list(sel.iteritems()))
# 将字典转换为Series
dict = {\'red\':100,\'back\':400,\'green\':300,\'pink\':900}
se3 = Series(dict)
print(se3)
Series数据获取
# Series 数据获取
sel = Series(data = [1,2,3,4], index = list(\'abcd\'))
print(sel)
# Series 对象同时支持位置和标签两种方式获取数据
print(\'索引下标:\',sel[\'c\'])
print(\'位置下标:\',sel[2])
# 获取不连续的数据
print(\'索引下标:\')
print(sel[[\'a\',\'c\']])
print(\'位置下标:\')
print(sel[[1,3]])
# 可以使用切片 取数据
print(\'位置切片:\')
print(sel[1:3]) # 左包含右不包含
print(\'索引切片:\')
print(sel[\'b\' : \'d\']) # 左右都包含
# 重新赋值索引的值
sel.index = list(\'dcba\')
print(sel)
# reindex 重新索引,会返回一个新的Series(调用reindex将会重新排序,缺失值用NaN填补)
print(sel.reindex([\'b\',\'a\',\'c\',\'d\',\'e\']))
# drop() 丢弃指定轴上的项
sel = pd.Series(range(10,15))
print(sel)
# drop
print(sel.drop([2,3]))
Series算术运算
# Series 进行算术运算
# 对 Series 的算术运算都是基于 index 来进行的
# 我们可以用 加减乘除(+,-,* ,/)这样的运算对两个 Series 进行运算
# pandas 根据索引 index 对响应的数据进行计算,结果将会以浮点数的形式储存,以避免丢失精度
# 如果 pandas 在 两个 Series 里找不到相同的 index ,对应的位置就返回一个空值 NaN
# series(data ,index) 第一个是数据 第二个是索引 感觉有点别扭
# 只有索引相同才进行计算,否则返回空值 NaN
series1 = pd.Series([1,2,3,4],[\'London\',\'HongKong\',\'HuBei\',\'Lagos\'])
series2 = pd.Series([1,3,6,4],[\'London\',\'Accra\',\'Lagos\',\'Delhi\'])
print(series1)
print(\'\n\')
print(series2)
print(\'\n\')
print(series1-series2)
print(\'\n\')
print(series1+series2)
print(\'\n\')
print(series1*series2)
print(\'\n\')
# 同样也支持numpy 的数组运算
sel = Series(data=[1,6,3,5],index=list(\'abcd\'))
print(\'原数组:\')
print(\'\n\')
print(sel)
print(\'\n\')
print(sel[sel>3]) # 布尔数组过滤 值大于3
print(\'\n\')
print(sel * 2) # 标量乘法
print(\'\n\')
print(np.square(sel)) # 可以直接加入到numpy的数学函数 平方
DataFrame
DataFrame的创建
# DataFrame 的创建
# 二维数据结构(表格形式储存)
# 三个参数 data index columns 分别代表 数据 行索引 列索引
# 使用二维数组
df1 = DataFrame(np.random.randint(0,10,(4,4)),index=[1,2,3,4],columns=[\'a\',\'b\',\'c\',\'d\'])
print(df1)
运行结果:
a b c d
1 2 9 6 1
2 0 5 5 0
3 4 4 7 8
4 4 3 5 2
# 使用字典进行创建(行索引由index决定,列索引由字典的键决定)
dict = {
\'Province\': [\'Guangdong\',\'Beijing\',\'Qinghai\',\'Fujian\'],
\'pop\': [1.3, 2.5, 1.1, 0.7],
\'year\': [2018, 2018, 2018, 2018]
}
df2 = pd.DataFrame(dict,index=[1,2,3,4])
print(df2)
# 使用 from_dict
dict2 = {\'a\':[1,2,3],\'b\':[4,5,6]}
df6 = pd.DataFrame.from_dict(dict2)
print(df6)
# 索引相同的情况下,相同索引的值会相对应,缺少的值会添加NaN
data={
\'Name\':pd.Series([\'zs\',\'ls\',\'we\'],index=[\'a\',\'b\',\'c\']),
\'Age\':pd.Series([\'10\',\'20\',\'30\',\'40\'],index=[\'a\',\'b\',\'c\',\'d\']),
\'country\':pd.Series([\'中国\',\'日本\',\'韩国\'],index=[\'a\',\'c\',\'b\'])
}
df3 = pd.DataFrame(data)
print(df3)
# to_dict() 方法将DataFrame 对象转换为字典
dict = df3.to_dict()
print(dict)
运行结果:
Province pop year
1 Guangdong 1.3 2018
2 Beijing 2.5 2018
3 Qinghai 1.1 2018
4 Fujian 0.7 2018
a b
0 1 4
1 2 5
2 3 6
Name Age country
a zs 10 中国
b ls 20 韩国
c we 30 日本
d NaN 40 NaN
{\'Name\': {\'a\': \'zs\', \'b\': \'ls\', \'c\': \'we\', \'d\': nan}, \'Age\': {\'a\': \'10\', \'b\': \'20\', \'c\': \'30\', \'d\': \'40\'}, \'country\': {\'a\': \'中国\', \'b\': \'韩国\', \'c\': \'日本\', \'d\': nan}}
DataFrame对象常用属性
# DataFrame 常用属性
df_dict={
\'name\':[\'James\',\'Curry\',\'Iversion\'],
\'age\':[\'18\',\'20\',\'19\'],
\'national\':[\'us\',\'China\',\'us\']
}
df = pd.DataFrame(data=df_dict,index=[\'0\',\'1\',\'2\'])
print(df)
print(\'\n\')
# 获取行数和列数
print(\'DataFrame的大小:\',df.shape)
# 获取行索引
print(\'获取DataFrame的行索引:\',df.index.tolist())
# 获取列索引
print(\'获取DataFrame的列索引:\',df.columns.tolist())
print(\'\n\')
# 获取数据的类型
print(\'获取DataFrame的数据类型:\')
print(df.dtypes)
print(\'\n\')
# 获取数据的维度
print(\'获取数据的维度:\',df.ndim)
print(\'\n\')
# values属性 也会以二维 ndarray 的形式返回 DataFrame 的数据
print(\'df的values属性:\')
print(df.values)
print(\'\n\')
# 展示df的概览
print(\'df的概览:\')
print(df.info())
print(\'\n\')
# 显示头几行 默认显示五行
print(df.head(2))
print(\'\n\')
# 显示后几行 默认显示后五行
print(df.tail(1))
print(\'\n\')
# 获取DataFrame的列
# 因为我们只获取一列,所以返回的是一个 Series
print(df[\'name\'])
print(type(df[\'name\']))
print(\'\n\')
# 如果获取的是多个列,那返回的就是一个 DataFrame 类型:
print(df[[\'name\',\'age\']])
print(type(df[[\'name\',\'age\']]))
print(\'\n\')
# 获取一行
print(df[0:1]) #左闭右开
print(\'\n\')
# 取多行
print(df[1:3])
print(\'\n\')
# 取多行里面的某一列(不能进行多行多列的选择)
# 注意 :df[]只能进行行选择,或列选择,不能同时多行多列选择 print(df[1:3][\'name\',\'age\'])
print(df[1:3][[\'name\',\'age\']])
print(\'\n\')
df_dict={
\'name\':[\'James\',\'Curry\',\'Iversion\'],
\'age\':[\'18\',\'20\',\'19\'],
\'national\':[\'us\',\'China\',\'us\']
}
df = pd.DataFrame(data=df_dict,index=[\'0\',\'1\',\'2\'])
print(df)
print(\'\n\')
# df.loc 通过标签索引行数据
# df.iloc 通过位置获取行数据
# 获取某一行某一列的数据
print(df.loc[\'0\',\'name\'])
print(\'\n\')
# 一行所有列
print(df.loc[\'0\',:])
print(\'\n\')
# 某一行多列的数据
print(df.loc[\'0\',[\'name\',\'age\']])
print(\'\n\')
# 选择间隔的多行多列
print(df.loc[[\'0\',\'2\'],[\'name\',\'national\']])
print(\'\n\')
# 选择连续的多行和间隔的多列
print(df.loc[\'0\':\'2\',[\'name\',\'national\']])
print(\'\n\')
# df.iloc 通过位置获取行数据 练习
# 取一行
print(df.iloc[1])
print(\'\n\')
# 取连续多行
print(df.iloc[0:2]) #左闭右开
print(\'\n\')
# 取间断的多行
print(df.iloc[[0,2],:])
print(\'\n\')
# 取某一列
print(df.iloc[:,1].tolist())
print(\'\n\')
# 按照坐标取某一个值
print(df.iloc[1,0])
print(\'\n\')
# 修改值
df.iloc[0,0]=\'pandas\'
print(df)
# DataFrame 中的排序方法
# ascending=False :降序排列 默认是升序
df = df.sort_values(by=\'age\',ascending=False)
print(df)
DataFrame修改index columns
import pandas as pd
from pandas import Series,DataFrame
import numpy as np
# dataframe 修改 行索引(index) 和 列索引(columns)
df1 = pd.DataFrame(np.arange(9).reshape(3,3),index=[\'bj\',\'sh\',\'gz\'],columns= [\'a\',\'b\',\'c\'])
print(df1)
# 修改 df1 的索引
# df1.index = [\'beijing\',\'shanghai\',\'guangzhou\']
# print(df1)
# 自定义map函数(x 是原有的行列值)
def test_map(x):
return x + \'_ABC\'
# inplace: 布尔值 ,默认为False 指定是否要返回新的DataFrame对象。如果为True,则在原df上进行修改
print(df1.rename(index=test_map,columns=test_map,inplace=False))
print(df1)
# 同时,rename 还可以传入字典,为某个 index 单独修改名称
df3 = df1.rename(index={\'bj\':\'beijing\'},columns={\'a\':\'aa\'})
print(df3)
# 列转化为索引
df1 = pd.DataFrame({\'X\':range(5),\'Y\':range(5),\'S\':list(\'abcde\'),\'Z\':[1,1,2,2,2]})
print(df1)
print(\'\n\')
# 指定一列为行索引(drop = False 指定同时保留作为索引的列)
result = df1.set_index(\'S\',drop=False)
result.index.name = None
print(result)
print(\'\n\')
# 指定一行行转化为列索引
result =df1.set_axis(df1.iloc[0],axis=1,inplace=False)
result.columns.name = None
print(result)
添加及删除数据
# 添加元素
df1 = pd.DataFrame([[\'Snow\',\'M\',22],[\'Tyrion\',\'M\',22],[\'Snana\',\'F\',18],[\'Arya\',\'F\',14]],
columns=[\'name\',\'gender\',\'age\'])
# 在数据最后再加上 score 一列
df1[\'score\'] = [80,98,67,90] #增加列的元素个数要和原数据列的个数一样
print(df1)
print(\'\n\')
col_name = df1.columns.tolist() # 将数据框中的列名全部提取出来放在列表里
col_name.insert(2,\'city\')
df1 = df1.reindex(columns=col_name)
print(df1)
print(\'\n\')
# 给city列索引进行赋值
df1[\'city\']=[\'北京\',\'山西\',\'湖北\',\'澳门\']
print(df1)
# df.insert(loc,column,value)
# lioc 要插入的位置 column 列名 value 值 前提:该列索引要不存在
# df1.insert(2,\'score\',[80,98,67,90])
# print(df1)
# 插入一行
df1 = pd.DataFrame([[\'Snow\',\'M\',22],[\'Tyrion\',\'M\',22],[\'Snana\',\'F\',18],[\'Arya\',\'F\',14]],
columns=[\'name\',\'gender\',\'age\'])
print(df1)
print(\'\n\')
# 先创建一个新的DataFrame对象,用来增加数据框的最后一行
new = pd.DataFrame({\'name\':\'lisa\',
\'gender\':\'F\',
\'age\':19
},index=[0])
print(new)
print(\'\n\')
print(\'在原始数据df1最后一行新增一行,用append方法:\')
# ignore_index=False表示不按原来的索引,从0开始自动递增
df1=df1.append(new,ignore_index=True)
print(df1)
# 合并对象
# ohjs:合并对象
# axis: 合并方式 ,默认0 表示按列进行合并,1表示按行合并
# ignore_index: 是否忽略索引
df1 = pd.DataFrame(np.arange(6).reshape(3,2),columns=[\'four\',\'five\'])
df2 = pd.DataFrame(np.arange(6).reshape(2,3),columns=[\'one\',\'two\',\'three\'])
print(\'df1:\')
print(df1)
print(\'df2:\')
print(df2)
# 按行合并
result = pd.concat([df1,df2],axis=1)
print(result)
# 按列合并
result = pd.concat([df1,df2],axis=0,ignore_index=True)
print(result)
# DataFrame的删除
# labels:要删除数据的标签
# axis: 0表示删除行,1表示删除列,默认0
# inplace: 是否在当前df中执行此操作
df2 = pd.DataFrame(np.arange(9).reshape(3,3),columns=[\'one\',\'two\',\'three\'])
print(df2)
df3 = df2.drop([\'one\'],axis=1,inplace = False)
print(df3)
print(df2)
数据处理
# 数组处理
from numpy import nan as NaN
# 通过 ** dropna() ** 过滤缺失数据
se = pd.Series([4,NaN,8,NaN,5])
print(se.tolist())
# 去掉无意义的值(NaN)
print(se.dropna().tolist())
print(se.notnull().tolist())
print(se.isnull().tolist())
# 通过 布尔序列 也能进行滤除
print(se[se.notnull()].tolist())
# 二维数组的过滤
df1 = pd.DataFrame([[1,2,3],[NaN,NaN,2],[NaN,NaN,NaN],[8,8,NaN]])
print(df1)
print(\'\n\')
# 默认消除所有包含 NaN 的列或行:
print(df1.dropna())
print(\'\n\')
# 传入 how = \'all\' 滤除全为 NaN 的行
print(df1.dropna(how = \'all\')) #默认情况下是 any ,只要有 nan 就删除
print(\'\n\')
# 传入 axis = 1 滤除列
print(df1.dropna(axis=1,how=\'all\'))
print(\'\n\')
# 传入 thresh = n 保留至少有 n 个非 NaN 数据的 行:
print(df1.dropna(thresh=1))
# 填充缺失数据
df1 = pd.DataFrame([[1,2,3],[NaN,NaN,2],[NaN,NaN,NaN],[8,8,NaN]])
print(df1)
print(\'\n\')
# 用常数填充 fillna
print(df1.fillna(0))
print(\'\n\')
# 传入 inplace = True 直接修改 原对象
# df1.fillna(0,inplace = True)
# print(df1)
# 通过字典填充不同的常数 这里的0,1,2 表示列索引
print(df1.fillna({0:10,1:20,2:30}))
print(\'\n\')
# 填充平均值
print(df1.fillna(df1.mean()))
print(\'\n\')
# 如果只填充一列
print(df1.iloc[:,1].fillna(5,inplace = True))
print(df1)
print(\'\n\')
# 传入 mothod = \'\' 改变插值方式:
df2 = pd.DataFrame(np.random.randint(0, 10, (5, 5)))
print(df2)
print(\'\n\')
df2.iloc[1:4, 3] = np.nan
df2.iloc[2:4, 4] = np.nan
print(df2)
print(\'\n\')
# 使用 (行)上面的值来填充 ffill 用后面的值来填充 bfill
print(df2.fillna(method=\'ffill\'))
print(\'\n\')
# 使用 limit= \'\' 限制填充行数:
print(df2.fillna(method=\'ffill\', limit=1))
print(\'\n\')
# axis 控制方向 1 表示列 这里是只填充一列 ,使用左边的值进行填充
print(df2.fillna(method=\'ffill\', limit=1, axis=1))
# 移除重复数据
# dataframe 中经常会出现重复行,利用 duplicated() 函数 返回每一行判断是否重复的结果
# 重复为 True
df1 = pd.DataFrame({\'A\': [1, 1, 1, 2, 2, 3, 1], \'B\': list(\'aabbbca\')})
print(df1)
print(\'\n\')
# 判断每一行是否重复(结果是 bool值,TRUE 代表重复的)
print(df1.duplicated().tolist())
print(\'\n\')
# 去除全部的重复行
print(df1.drop_duplicates())
print(\'\n\')
# 指定列去除重复行
print(df1.drop_duplicates([\'A\']))
print(\'\n\')
# 保留重复行中的最后一行
print(df1.drop_duplicates([\'A\'], keep=\'last\'))
print(\'\n\')
# 去除重复的同时改变DataFrame对象
df1.drop_duplicates([\'A\', \'B\'], inplace=True)
print(df1)
数据合并
# 数据合并
# 使用 join 合并 着重关注的是行的合并
import pandas as pd
df3 = pd.DataFrame({\'Red\':[1,3,5],\'Green\':[5,0,3]},index=list(\'abc\'))
df4 = pd.DataFrame({\'Blue\':[1,9,8],\'Yellow\':[6,6,7]},index=list(\'cde\'))
print(df3)
print(df4)
# 简单合并(默认是left 左连接,以左侧 dfs 为例)
# 左连接
# df3.join(df4,how=\'left\')
# 右连接
# df3.join(df4,how=\'right\')
# 外连接
# df3.join(df4,how=\'outer\')
# 合并多个DataFrame对象
df5 = pd.DataFrame({\'Brown\':[3,4,5],\'White\':[1,1,2]},index=list(\'aed\'))
df3.join([df4,df5])
# 使用merge,看重的是列合并
df1 = pd.DataFrame({\'名字\': list(\'ABCDE\'), \'性别\': [\'男\', \'女\', \'男\', \'男\', \'女\'], \'职称\':
[\'副教授\', \'讲师\', \'助教\', \'教授\', \'助教\']}, index=range(1001, 1006))
df1.columns.name = \'学院老师\'
df1.index.name = \'编号\'
print(df1)
print(\'\n\')
df2 = pd.DataFrame({\'名字\': list(\'ABDAX\'), \'课程\': [\'C++\', \'计算机导论\', \'汇编\', \'数据结构\', \'马克思原理\'], \'职称\':
[\'副教授\', \'讲师\', \'教授\', \'副教授\', \'讲师\']}, index=range(1001, 1006))
df2.columns.name = \'课程\'
df1.index.name = \'编号\'
print(df2)
print(\'\n\')
# 默认下是根据左右对象中出现同名的列作为连接的键,且连接方式是 how = \'inner\'
print(pd.merge(df1,df2)) #返回匹配的
print(\'\n\')
# 指定列名合并
# pd.merge(df1,df2,on=\'名字\',suffixes=[\'_1\',\'_2\']) # 返回匹配的
# 连接方式,根据左侧为准
pd.merge(df1,df2,how=\'left\')
# 根据右侧为准
pd.merge(df1,df2,how=\'right\')
# 所有
pd.merge(df1,df2,how=\'outer\')
# 根据多个键进行连接
pd.merge(df1,df2,on=[\'职称\',\'名字\'])
多层索引(扩展)
# 多级索引
# Series
s = Series(np.random.randint(0, 150, size=6), index=[[\'a\', \'a\', \'b\', \'b\', \'c\', \'c\'],
[\'期中\', \'期末\', \'期中\', \'期末\', \'期中\', \'期末\']])
print(s)
print(\'\n\')
# 取一个第一级索引
print(s[\'a\'])
print(\'\n\')
# 取多个第一级索引
print(s[[\'a\',\'b\']])
print(\'\n\')
# 根据索引获取值
print(s[\'a\',\'期末\'])
print(\'\n\')
# loc 方法取值
print(s.loc[\'a\'])
print(s.loc[[\'a\',\'b\']])
print(s.loc[\'a\',\'期末\'])
print(\'\n\')
# iloc 方法取值(iloc 计算的是最内层索引)
print(s.iloc[1])
print(s.iloc[1:4])
时间序列
# 时间序列
import pandas as pd
import numpy as np
# 生成一段时间范围
data = pd.date_range(start=\'20190501\',end=\'20190530\')
print(data)
# freg: 日期偏移量 取值为 string 或 DateOffset,默认为\'D\', freg=\'1h30min\'
# freg =\'10D\'
# periods;固定时期,取值为整数或None 就是生成几个数据
date = pd.date_range(start=\'20190501\',periods=10,freq=\'10D\')
print(date)
# 时间序列在series中的作用
# 可以将时间作为索引
index = pd.date_range(start=\'20190101\', periods=10)
df = pd.Series(np.random.randint(0,10,size=10),index=index)
print(df)
# truncate 这个函数 根据日期过滤 before 之后的日期 after :之前的日期
after = df.truncate(after=\'2019-01-2\')
print(after)
# 日期的一些常见属性
long_ts = pd.Series(np.random.randn(
1000), index=pd.date_range(\'1/1/2019\', periods=1000))
print(long_ts)
print(\'\n\')
# 根据年份获取
# result = long_ts[\'2020\']
# print(result)
# print(\'\n\')
# 根据年份和日期获取
# result = long_ts[\'2020-05\']
# print(result)
# 使用切片
# result = long_ts[\'2020-05-01\':\'2020-05-06\']
# print(result)
# 通过between_time()返回指定时间段的数据集
index = pd.date_range(\'2018-03-17\', \'2018-03-30\', freq=\'2H\')
ts = pd.Series(np.random.randn(157), index=index)
print(ts.between_time(\'7:00\', \'17:00\'))
print(\'\n\')
# 这些操作也适用于dataframe
index = pd.date_range(\'1/1/2019\',periods=100)
df = pd.DataFrame(np.random.rand(100,4),index=index)
print(df.loc[\'2019-04\'])
分组聚合(常用)
# 分组聚合
df = pd.DataFrame({
\'name\': [\'BOSS\', \'Lilei\', \'Lilei\', \'Han\', \'BOSS\', \'BOSS\', \'Han\', \'BOSS\'],
\'Year\': [2016, 2016, 2016, 2016, 2017, 2017, 2017, 2017],
\'Salary\': [999999, 20000, 25000, 3000, 9999999, 999999, 3500, 999999],
\'Bonus\': [100000, 20000, 20000, 5000, 200000, 300000, 3000, 400000]
})
print(df)
# 根据name 这一列进行分组
group_by_name = df.groupby(\'name\')
print(type(group_by_name))
# 查看分组
print(\'\n\')
print(group_by_name.groups)
print(\'\n\')
# 分组后的数量
print(group_by_name.count())
print(\'\n\')
# 查看分组的情况
for name,group in group_by_name:
print(name) # 组的名字
print(group) # 组具体内容
print(\'\n\')
# 可以选择分组
print(group_by_name.get_group(\'BOSS\'))
print(\'\n\')
# 按照某一列进行分组 ,将name 这一列作为分组的键,对year 进行分组
group_by_name = df[\'Year\'].groupby(df[\'name\'])
print(group_by_name.count())
print(\'\n\')
# 按照多列进行分组
group_by_name_year = df.groupby([\'name\',\'Year\'])
print(\'分组数量:\')
print(group_by_name_year.count())
print(\'按照多列进行分组:\')
for name,group in group_by_name_year:
print(name)
print(group)
print(\'\n\')
# 可以选择分组
print(group_by_name_year.get_group((\'BOSS\',2016)))
# \'\'\'
# 聚合函数
# mean 计算分组平均值
# count 分组中非NA值的数量
# sum 非NA值的和
# median 非NA值的算术中位数
# std 标准差
# var 方差
# min 非NA值的最小值
# max 非NA值的最大值
# prod 非NA值的积
# first 第一个非NA值
# last 最后一个非NA值
# mad 平均绝对偏差
# mode 模
# abs 绝对值
# sem 平均值的标准误差
# skew 样品偏斜度(三阶矩)
# kurt 样品峰度(四阶矩)
# quantile 样本分位数(百分位上的值)
# cumsum 累积总和
# cumprod 累积乘积
# cummax 累积最大值
# cummin 累积最小值
# \'\'\'# \'\'\'
# 聚合函数
# mean 计算分组平均值
# count 分组中非NA值的数量
# sum 非NA值的和
# median 非NA值的算术中位数
# std 标准差
# var 方差
# min 非NA值的最小值
# max 非NA值的最大值
# prod 非NA值的积
# first 第一个非NA值
# last 最后一个非NA值
# mad 平均绝对偏差
# mode 模
# abs 绝对值
# sem 平均值的标准误差
# skew 样品偏斜度(三阶矩)
# kurt 样品峰度(四阶矩)
# quantile 样本分位数(百分位上的值)
# cumsum 累积总和
# cumprod 累积乘积
# cummax 累积最大值
# cummin 累积最小值
# \'\'\'
# 使用 agg()函数做聚合运算 通用 通过参数传参
for name,group in df1.groupby(\'key1\'):
print(name)
print(group)
print(\'\n\')
print(df1.groupby(\'key1\').agg(\'sum\'))
# 优势在于可以同时做多个聚合运算
print(df1.groupby(\'key1\').agg([\'sum\',\'mean\',\'std\']))
# agg()还可以传入自定义函数
def peak_range(df):
return df.max()-df.min()
print(df1.groupby(\'key1\').agg(peak_range))
print(\'\n\')
print(\'同时应用多个聚合函数:\')
# 同时应用多个聚合函数
print(df1.groupby(\'key1\').agg([\'mean\',\'std\',\'count\',peak_range]))
print(\'\n\')
# 通过元组提供新的列名 就是别名
print(df1.groupby(\'key1\').agg([\'mean\',\'std\',\'count\',(\'range\',peak_range)]))
print(\'\n\')
print(\'给每列作用不同的函数:\')
# 给每列作用不同的函数
dict_mapping = {
\'Data1\':[\'mean\',\'max\'],
\'Data2\':\'sum\'
}
print(df1.groupby(\'key1\').agg(dict_mapping))
# apply() 函数 : pandas 中自由度最高的函数
# agg() 函数 只是用来数值计算,一些非数值会被过滤,存在缺陷
df1 = pd.DataFrame(
{
\'sex\': list(\'FFMFMMF\'),
\'smoker\': list(\'YNYYNYY\'),
\'age\': [21, 30, 17, 37, 40, 18, 26],
\'weight\': [120, 100, 132, 140, 94, 89, 123]
}
)
print(df1)
print(\'\n\')
# 判断抽烟年龄
def bin_age(age):
if age >= 18:
return \'早日戒烟\'
else:
return \'很好啊啊\'
print(df1[\'age\'].apply(bin_age))
# df1[\'age\']=df1[\'age\'].apply(bin_age)
# print(df1)
# 取出抽烟和不抽烟的体重的前二
def top(smoker,col,n=5):
return smoker.sort_values(by=col)[-n:]
df1.groupby(\'smoker\').apply(top,col=\'weight\',n=2)