创建索引名称已由现有对象使用_Day080 多层索引

多层索引

多层索引(MultiIndex),具有多个层次索引,有些类似于根据索引进行分组的形式。通过多层次索引,我们可以使用高层次索引,来操作整个索引组的数据。

创建方式

第一种

我们在创建Series或者DataFrame时,通过index(columns)参数传递多维数组,进而创建多级索引。多级索引可以通过names属性设置名称,每级索引的元素个数相同。

第二种

我们MultiIndex类的方法创建MultiIndex对象,然后作为Sereis或者DataFrame的index(columns)参数值。同样可以通过names参数指定多层索引的名称

  • from_arrays:接收一个多维数组参数,高维指定高层索引,低纬指定底层索引
  • from_tuples:接收一个元素作为列表,每个元组指定每个索-引->(高维索引,低纬索引)
  • from_product:接收一个可迭代对象列表,根据可迭代对象列表中元素的笛卡尔积创建多级索引

多层索引操作

对于多层索引,同样支持单层索引的相关操作,例如,索引元素、切片、索引数组选择元素等。我们也可以根据多级索引,按照层次逐级选择元素。多层元素优势,通过高层次索引,来操作整个索引组的数据 操作语法:

  • s[操作]
  • s.loc[操作]
  • s.iloc[操作]

操作可以是索引、切片、数组索引

Series多层索引

  • loc:标签索引操作,通过多层索引,获取该索引对应的一组值
  • iloc:位置索引操作,获取对应位置的元素值,与是否多层索引无关
  • s[操作]的操作逻辑见下,不推荐使用
  • 对于索引(单级),首先按照标签选择,如标签不存在,按照位置选择
  • 对于多级索引,按照标签进行选择
  • 对于切片,如果提供的是整数,按照位置选择,否则按照标签选择
  • 对于数组索引,如果数组元素都是整数,根据位置进行索引,否则根据标签索引

DataFrame多层索引

  • loc:标签索引操作,通过多层索引,获取该索引对应的一组值
  • iloc:位置索引操作,获取对应位置的一行数据,与是否多层索引无关
  • s[操作]的操作逻辑见下,不推荐使用
  • 对于索引,根据标签获取相应列。如果是多层索引,获得多列
  • 对于数组索引,根据标签,获取相应列。如果是多层索引,获得多列
  • 对于切片,先按照标签索引,然后再按照位置进行索引,获取行的数据

In [2]:

import numpy as np
import pandas as pd

代码举例:需求如下

湖南 长沙 1 2

​ 衡阳 3 4

北京 海淀 5 6

​ 昌平 7 8

In [25]:

# Series创建多级索引,通过index参数指定
# 单层索引,index参数指定一维数组
# s = pd.Series([1,2,3,4],index=['a','b','c','d'])
# display(s)
# 多级 索引,index参数值指定多维数组
# s = pd.Series([1,2,3,4],index=[['湖南','湖南','北京','北京'],['长沙','衡阳','海淀','昌平']])
# display(s)
# # 多级索引,为每一层索引指定名称
# s.index.names=['省份','城市']
# display(s)


# Series创建多级索引,通过创建MultiIndex对象,设置给index参数
# from_arrays,通过列表的方式创建 [[第1级索引],[第2级索引],.....[第n级索引]]
# m = pd.MultiIndex.from_arrays([['湖南','湖南','北京','北京'],['长沙','衡阳','海淀','昌平']])
# s = pd.Series([1,2,3,4],index=m)
# display(s)

# from_tuples 通过元祖构成列表   [(第1级索引元素,第2级索引元素),(第1级索引元素,第2级索引元素)....]
# m = pd.MultiIndex.from_tuples([('湖南','长沙'),('湖南','衡阳'),('北京','海淀'),('北京','昌平')])
# s = pd.Series([1,2,3,4],index=m)
# display(s)

# from_product 通过笛卡尔积方式创建MultiIndex对象设置给index参数
m =  pd.MultiIndex.from_product([['湖南','北京'],['长沙','衡阳','海淀','昌平']])
s = pd.Series([1,2,3,4,5,6,7,8],index=m)
display(s)
湖南  长沙    1
    衡阳    2
    海淀    3
    昌平    4
北京  长沙    5
    衡阳    6
    海淀    7
    昌平    8
dtype: int64

In [30]:

# DataFrame行多级索引
# 它和Series多级索引创建没有区别
# 方式1 index参数多维数组 
# df = pd.DataFrame(np.arange(1,9).reshape(4,2),index=[['湖南','湖南','北京','北京'],['长沙','衡阳','海淀','昌平']])
# display(df)

# 方式2 通过MultiIndex类的方法(from_arrays from_tuples from_product)创建MultiIndex对象,设置index,
# from_arrays
# m = pd.MultiIndex.from_arrays([['湖南','湖南','北京','北京'],['长沙','衡阳','海淀','昌平']])
# df = pd.DataFrame(np.arange(1,9).reshape(4,2),index=m)
# display(df)

# from_tuples 
# m = pd.MultiIndex.from_tuples([('湖南','长沙'),('湖南','衡阳'),('北京','海淀'),('北京','昌平')])
# df = pd.DataFrame(np.arange(1,9).reshape(4,2),index=m)
# display(df)

# from_product
m = pd.MultiIndex.from_product([['湖南','北京'],['长沙','衡阳','海淀','昌平']])
df = pd.DataFrame(np.arange(1,17).reshape(8,2),index=m)
display(df)

c16d38b2ae30ba1b99f4fc07ea49dcc6.png

In [185]:

# DataFrame创建列多层索引和行创建多层索引类似,区别在创建DataFrame设置给参数columns
df = pd.DataFrame(np.array([[1,1,1,1],[2,1,2,1]]),index=['七里香','双节棍'],columns=[['中文','中文','English','English'],['喜欢','不喜欢','like','dislike']])
display(df)

Out[185]:

七里香    1
双节棍    2
Name: (中文, 喜欢), dtype: int32

In [155]:

# 标签来切片,注意切片的标签需要排好序(字典顺序),否则报错。使用sort_index方法对索引进行排序(字典顺序),再切片
s= pd.Series([1,2,3,4],index=[['b','a','a','b'],['长沙','衡阳','海淀','昌平']])
display(s)
s  = s.sort_index()
display(s)
display(s.loc['b':'a'])
b  长沙    1
a  衡阳    2
   海淀    3
b  昌平    4
dtype: int64
a  海淀    3
   衡阳    2
b  昌平    4
   长沙    1
dtype: int64
Series([], dtype: int64)

In [161]:

# Sereis多层索引操作
# loc标签操作
s = pd.Series([1,2,3,4],index=[['湖南','湖南','北京','北京'],['长沙','衡阳','海淀','昌平']])
display(s)
# 直接使用外层索引访问,可以获得外层索引对应的一组值
# display(s.loc['湖南'])
# 多层索引访问中,不支持直接使用内存索引访问
# 因为多层索引访问中,首先从外层索引找,外层没有‘长沙’标签,报错
# display(s.loc['长沙'])
# 使用外层+内存索引逐层访问
# display(s.loc['湖南','长沙'])

# iloc位置操作
# 根据位置访问,与是否存在多层索引没有关系的
# display(s.iloc[0])

# 切片操作
# 标签来切片,注意切片的标签需要排好序(字典顺序),否则报错
# s = s.sort_index()
# display(s)
# display(s.loc['北京':'湖南'])
# 根据位置切片
# display(s.iloc[0:2])

# 数组索引,也许要对索引进行进行排序
s = s.sort_index()
display(s.loc[['北京','湖南']])
湖南  长沙    1
    衡阳    2
北京  海淀    3
    昌平    4
dtype: int64
北京  昌平    4
    海淀    3
湖南  衡阳    2
    长沙    1
dtype: int64

省份 年 湖南 2017 8000

​ 2018 8100

北京 2017 1200

​ 2018 1150

In [176]:

m =pd.MultiIndex.from_product([['湖南','北京'],['2017','2018']])
s = pd.Series(np.array([8000,8100,1200,1150]),index=m)
display(s.loc[:,'2017'])
湖南    8000
北京    1200
dtype: int32

In [179]:

m =pd.MultiIndex.from_product([['湖南','北京'],['2017','2018']])
df = pd.DataFrame(np.array([[8000],[8100],[1200],[1150]]),index=m)
display(df)

# loc 标签的访问
# 直接使用外层索引访问
# display(df.loc['湖南'])
# 不支持直接使用内层索引访问
# display(df.loc['2017'])
# 外层+内层逐层访问,得到一行数据
# display(df.loc['湖南','2017'])
# display(df.loc[('湖南','2017')])

# iloc位置访问,是否存在多层索引没有关系的
# display(df.iloc[0])

# 切片操作
# 标签的切片(既包含起始也包含终止标签的数据)
# 先对索引进行排序
# df = df.sort_index()
# display(df)
# # display(df.loc['北京':'湖南'])
# # 混合操作,设置axis=0,否则2017当做列索引名称。但是Series不必 
# display(df.loc(axis=0)[:,'2017'])

# 位置切片(包含起始位,不包含终止位)
# display(df.iloc[0:2])

# 数组索引,也需要索引有序
df = df.sort_index()
display(df)
display(df.loc[['北京','湖南']])

| | | 0 | | ---- | ---- | ---- | | 湖南 | 2017 | 8000 | | | 2018 | 8100 | | 北京 | 2017 | 1200 | | | 2018 | 1150 |

| | | 0 | | ---- | ---- | ---- | | 北京 | 2017 | 1200 | | | 2018 | 1150 | | 湖南 | 2017 | 8000 | | | 2018 | 8100 |

| | | 0 | | ---- | ---- | ---- | | 北京 | 2017 | 1200 | | | 2018 | 1150 | | 湖南 | 2017 | 8000 | | | 2018 | 8100 |

交换索引

我们可以调用DataFrame对象的swaplevel方法交换两个层级索引。该方法默认对倒数第2层和倒数第1层进行交换。 我们可以指定交换层级,层次从0开始,由外向内递增,也可以指定负值,负值表示倒数第n层。 我们可以通过层级索引的名称进行交换。

In [131]:

# m = pd.MultiIndex.from_arrays([['湖南','湖南','北京','北京'],['东部','西部','东部','西部']])
# df = pd.DataFrame(np.arange(1,9).reshape(4,2),index=m)
# display(df)

df = pd.DataFrame(np.arange(1,9).reshape(4,2),index=[['A','A','B','B'],['a1','a1','b1','c1'],['a2','b2','b2','c2']])
display(df)

# 默认交换最里面2个层级索引
# display(df.swaplevel())
# 索引的层级从外到内,第0层,第1层,第2层
display(df.swaplevel(0,2))
# 索引的层级可以为负值,-1,-2,-3,-1最内层
display(df.swaplevel(-3,-1))

# 根据层级索引名称交换
df.index.names=['layer0','layer1','layer2']
display(df.swaplevel('layer0','layer2'))

索引排序

我们可以使用sort_index对索引进行排序处理

  • level:指定根据哪一层排序,默认最外层。level值可以是数值,索引名或者二者构成的列表
  • inplace:是否就地修改,默认为False

In [144]:

# df = pd.DataFrame(np.arange(1,9).reshape(4,2),index=[['A','A','B','B'],['a1','a1','b1','c1'],['a2','b2','b2','c2']])
# df = pd.DataFrame(np.arange(1,9).reshape(4,2),index=[['B','A','B','A'],['a1','a1','b1','c1'],['a2','b2','b2','c2']])
# display(df)

# # 索引排序,默认对最外层的索引排序(字典升序)
# # display(df.sort_index())
# # 自定义对哪个层级的索引排序
# # df.sort_index(level=1)
# df.sort_index(level=1,ascending=False)

df = pd.DataFrame(np.array([[1,1,1,1],[2,1,2,1]]),index=['七里香','双节棍'],columns=[['Chinese','Chinese','English','English'],['喜欢','不喜欢','like','dislike']])
display(df)
display(df.sort_index(axis=1,ascending=False))

索引堆叠

通过DataFrame对象的stack方法,可以进行索引堆叠,即将指定成绩的列转换成行。

  • level参数指定转换的层级,默认为-1

通过DataFrame对象的unstack方法,可以取消索引堆叠,即将指定层级的行转换成列。

  • level参数指定转换的层级,默认为-1
  • fill_value参数:指定填充值,默认为NaN

In [218]:

# 对索引进行堆叠操作,会将列索引堆加在行最内层索引上。
# 当对索引进行取消堆叠的操作,将行索引堆加列的最内层索引上
# 索引堆叠使得访问数据更加灵活

# df = pd.DataFrame(np.arange(1,9).reshape(4,2),index=[['B','A','B','A'],['a1','a1','b1','c1'],['a2','b2','b2','c2']])
# df.sort_index(inplace=True)
# display(df)

# m = pd.MultiIndex.from_arrays([['湖南','湖南','北京','北京'],['东部','西部','东部','西部']])
# df = pd.DataFrame(np.arange(1,9).reshape(4,2),index=m,columns=['人口','GDP'])
# display(df)

# # 当对索引进行取消堆叠的操作,将行索引堆加列的最内层索引上
# df = df.unstack()
# display(df)
# # 访问人口是东部的数据
# display(df['人口','东部'])

# df = pd.DataFrame(np.arange(1,9).reshape(4,2),index=[['B','A','B','A'],['a1','a1','b1','c1'],['a2','b2','b2','c2']])
# df.index.names=['layer0','layer1','layer2']
# df.sort_index(inplace=True)
# display(df)

# 取消堆叠操作,可能会产生NaN,避免空值,填充数据使用fill_value
# df = df.unstack(fill_value=0)
# display(df)

# level参数自定义层级,默认是行最内层索引
# df = df.unstack(level=1,fill_value=0)
# display(df)

# 除了自定义层级数值,还可以指定索引的名称
# df = df.unstack(level='layer0',fill_value=0)
# display(df)

# 索引的堆叠操作 对索引进行堆叠操作,会将列索引堆加在行最内层索引上
df = pd.DataFrame(np.array([[1,1,1,1],[2,1,2,1]]),index=['七里香','双节棍'],columns=[['中文','中文','English','English'],['喜欢','不喜欢','like','dislike']])
display(df)
# 七里香歌曲中中文信息
df = df.stack(0)
display(df)
display(df.loc['七里香','中文'])
dislike    NaN
like       NaN
不喜欢        1.0
喜欢         1.0
Name: (七里香, 中文), dtype: float64

索引设置

在DataFrame中,如果我们需要将现有的某一或者多列作为行索引,可以调用set_index方法实现。参数如下

  • drop:是否丢弃作为新索引列,默认为True
  • append:是否以追加方式设置索引,默认为False
  • inplace:是否就地修改,默认为False

In [248]:

df = pd.DataFrame({'stuno':[1,2,3],'name':['zs','ls','ww'],'age':[20,21,2]})
display(df)

# set_index设置索引,设置参数指定列,充当索引
# display(df.set_index('stuno'))

# 设置层级行索引
# display(df.set_index(['stuno','name']))

# 默认情况下,充当行索引的列数据丢弃,设置drop=false保留列数据
# display(df.set_index('stuno',drop=False))

# append用来设置是否以追加的方式设置索引,默认False(取代之前的索引)
df.set_index('stuno',inplace=True)
display(df)
df.set_index('name',inplace=True,append=True)
display(df)

重置索引

调用DataFrame的reset_index重置索引,与set_index正相反。参数如下

  • level:重置索引层级,默认重置所有层级的索引。如果重置所有索引,将会创建默认整数序列索引
  • drop:是否丢弃重置索引列,默认为False
  • inplace:是否就地修改,默认为False

In [252]:

df = pd.DataFrame({'stuno':[1,2,3],'name':['zs','ls','ww'],'age':[20,21,2]})
# display(df)
# 设置层级行索引
df.set_index(['stuno','name'],inplace=True)
display(df)

# 重置索引,默认重置所有层级的行索引,重新生成整数序列为行索引
# display(df.reset_index())

# level指定重置索引的层级
# display(df.reset_index(1))

# 重置索引后,默认将重置的行索引充当回新的列,如果不想将重置的行索引充当回新的列,指定drop=True
display(df.reset_index(1,drop=True))

| | | age | | ----- | ---- | ---- | | stuno | name | | | 1 | zs | 20 | | 2 | ls | 21 | | 3 | ww | 2 |

| | age | | ----- | ---- | | stuno | | | 1 | 20 | | 2 | 21 | | 3 | 2 |

分组与聚合

分组与聚合操作与数据库分组和聚合类似

groupby分组

我们可以通过groupby方法对Series或DataFrame对象实现分组操作。该方法返回一个分组对象。分组对象属性和方法

  • groups属性:返回一个字典类型对象,包含分组信息
  • size方法:返回每组记录数量
  • describe方法:分组查看统计信息

迭代

使用for循环对分组对象进行迭代。迭代每次返回一个元祖,第1个元素为分组的key,第2个为改组对应的数据

分组方式

使用groupby进行分组时,分组参数可以是如下形式:

  • 索引名:根据该索引进行分组
  • 索引名构成的数组:根据数组中多个索引进行分组
  • 字典或者Series:key指定索引,value指定分组依据,value值相等的分为一组
  • 函数:接受索引,返回分组依据的value值

apply

对分组对象,可以调用apply函数,该函数接收每个组的数据,返回操作之后的结果。apply最后将每个组的操作结果进行合并(concat)

聚合

可以在分组对象进行聚合(多个值变成一个值)。例如,mean(),sum()等 除此之外,我们可调用agg方法,实现自定义聚合方式。函数接收一行或者一列数据,返回该行或者列聚合后的结果

In [40]:

df = pd.DataFrame({'部门':['研发','财务','研发','财务'],'项目组':['一组','二组','二组','一组'],
                   '姓名':['张三','李四','王五','赵六'],'年龄':[20,22,23,24],'利润':[5,10,10,25]})
display(df)

# 根据单个列说明分组,返回分组对象
group = df.groupby('部门')
# 分组对象不像列表,可以将分组后内容直接输出,其类型是DataFrameGroupBy
display(group)

# 分组对象是一个可迭代的对象,通过for循环来查看分组信息
# for item in group:
#     display(type(item))

# 对分组对象迭代返回的元素对象(k,v)
for k,v in group:
    display(k,v)

# 查看分组对象属性和方法
# groups属性得到分组信息字典 key:分组数据的索引
display(group.groups)
# 得到每组记录条数
display(group.size())
display(group.describe())

| | 利润 | 姓名 | 年龄 | 部门 | 项目组 | | ---- | ---- | ---- | ---- | ---- | ------ | | 0 | 5 | 张三 | 20 | 研发 | 一组 | | 1 | 10 | 李四 | 22 | 财务 | 二组 | | 2 | 10 | 王五 | 23 | 研发 | 二组 | | 3 | 25 | 赵六 | 24 | 财务 | 一组 |

<pandas.core.groupby.DataFrameGroupBy object at 0x0000000009C81DA0>
'研发'

| | 利润 | 姓名 | 年龄 | 部门 | 项目组 | | ---- | ---- | ---- | ---- | ---- | ------ | | 0 | 5 | 张三 | 20 | 研发 | 一组 | | 2 | 10 | 王五 | 23 | 研发 | 二组 |

'财务'

| | 利润 | 姓名 | 年龄 | 部门 | 项目组 | | ---- | ---- | ---- | ---- | ---- | ------ | | 1 | 10 | 李四 | 22 | 财务 | 二组 | | 3 | 25 | 赵六 | 24 | 财务 | 一组 |

{'研发': Int64Index([0, 2], dtype='int64'),
 '财务': Int64Index([1, 3], dtype='int64')}
部门
研发    2
财务    2
dtype: int64

In [50]:

df = pd.DataFrame({'部门':['研发','财务','研发','财务'],'项目组':['一组','二组','二组','一组'],
                   '姓名':['张三','李四','王五','赵六'],'年龄':[20,22,23,24],'利润':[5,10,10,25]})
display(df)

# 根据单个列说明分组,返回分组对象
# group = df.groupby('部门')
# for k,v in group:
#     display(k,v)

# 多个索引列分组
# group = df.groupby(['部门','项目组'])
# for k,v in group:
#     display(k,v)

# 根据函数分组
# df = df.set_index('利润')
# display(df)
# # 函数需要有一个参数,用来接收行索引值。函数还需要具有返回值,用来指定组
# def group_handle(index):
#     if index<10:
#         return 0
#     return 1
# # 需求:将利润<10和>=10的人员分组
# group = df.groupby(group_handle)
# for k,v in group:
#     display(k,v)

# 字典
# 根据行索引分组
# group = df.groupby({0:0,1:0,2:1,3:1})
# for k,v in group:
#     display(k,v)

# 根据列索引值分组
df.groupby
group = df.groupby({'姓名':0,'利润':0,'部门':1,'项目组':1},axis=1)
for k,v in group:
    display(k,v)

| | 利润 | 姓名 | 年龄 | 部门 | 项目组 | | ---- | ---- | ---- | ---- | ---- | ------ | | 0 | 5 | 张三 | 20 | 研发 | 一组 | | 1 | 10 | 李四 | 22 | 财务 | 二组 | | 2 | 10 | 王五 | 23 | 研发 | 二组 | | 3 | 25 | 赵六 | 24 | 财务 | 一组 |

0.0

| | 利润 | 姓名 | | ---- | ---- | ---- | | 0 | 5 | 张三 | | 1 | 10 | 李四 | | 2 | 10 | 王五 | | 3 | 25 | 赵六 |

1.0

| | 部门 | 项目组 | | ---- | ---- | ------ | | 0 | 研发 | 一组 | | 1 | 财务 | 二组 | | 2 | 研发 | 二组 | | 3 | 财务 | 一组 |

In [56]:

df = pd.DataFrame({'部门':['研发','财务','研发','财务'],'项目组':['一组','二组','二组','一组'],
                   '姓名':['张三','李四','王五','赵六'],'年龄':[20,22,23,24],'利润':[5,10,10,25]})
display(df)

group= df.groupby('部门')
for k,v in group:
    display(k,v)

# 对分组数据统计(聚合)
# 利润 年龄 数值型进行统计;姓名,项目组是字符串,不会统计; 部门属于分组字段,不参与统计
display(group.sum())

# 对比DataFrame
# 所有数值型数据相加,字符串做拼接
display(df.sum())
# 设置DataFrame只对数值型 数据统计,指定参数numeric_only=True
display(df.sum(numeric_only=True))

# 对分组数据中指定列数据进行统计
display(group['利润'].sum())

| | 利润 | 姓名 | 年龄 | 部门 | 项目组 | | ---- | ---- | ---- | ---- | ---- | ------ | | 0 | 5 | 张三 | 20 | 研发 | 一组 | | 1 | 10 | 李四 | 22 | 财务 | 二组 | | 2 | 10 | 王五 | 23 | 研发 | 二组 | | 3 | 25 | 赵六 | 24 | 财务 | 一组 |

'研发'

| | 利润 | 姓名 | 年龄 | 部门 | 项目组 | | ---- | ---- | ---- | ---- | ---- | ------ | | 0 | 5 | 张三 | 20 | 研发 | 一组 | | 2 | 10 | 王五 | 23 | 研发 | 二组 |

'财务'

| | 利润 | 姓名 | 年龄 | 部门 | 项目组 | | ---- | ---- | ---- | ---- | ---- | ------ | | 1 | 10 | 李四 | 22 | 财务 | 二组 | | 3 | 25 | 赵六 | 24 | 财务 | 一组 |

| | 利润 | 年龄 | | ---- | ---- | ---- | | 部门 | | | | 研发 | 15 | 43 | | 财务 | 35 | 46 |

利润           50
姓名     张三李四王五赵六
年龄           89
部门     研发财务研发财务
项目组    一组二组二组一组
dtype: object
利润    50
年龄    89
dtype: int64
部门
研发    15
财务    35
Name: 利润, dtype: int64

In [92]:

df = pd.DataFrame({'部门':['研发','财务','研发','财务'],'项目组':['一组','二组','二组','一组'],
                   '姓名':['张三','李四','王五','赵六'],'年龄':[20,22,23,24],'利润':[5,10,10,25]})
display(df)

group= df.groupby('部门')
for k,v in group:
    display(k,v)

# 对分组对象进行apply,apply接收函数实现对分组数据操作
# 函数具有一个参数,依次接收分组数据,返回每一个分组处理的结果,
# 注意点,apply对于第一个分组数据会调用2次,但是不会影响操作结果
# group.apply(lambda x:display(x,type(x)))

# 对每组数据进行求和统计
display(group.apply(lambda x:x.sum(numeric_only=True)))

| | 利润 | 姓名 | 年龄 | 部门 | 项目组 | | ---- | ---- | ---- | ---- | ---- | ------ | | 0 | 5 | 张三 | 20 | 研发 | 一组 | | 1 | 10 | 李四 | 22 | 财务 | 二组 | | 2 | 10 | 王五 | 23 | 研发 | 二组 | | 3 | 25 | 赵六 | 24 | 财务 | 一组 |

'研发'

| | 利润 | 姓名 | 年龄 | 部门 | 项目组 | | ---- | ---- | ---- | ---- | ---- | ------ | | 0 | 5 | 张三 | 20 | 研发 | 一组 | | 2 | 10 | 王五 | 23 | 研发 | 二组 |

'财务'

| | 利润 | 姓名 | 年龄 | 部门 | 项目组 | | ---- | ---- | ---- | ---- | ---- | ------ | | 1 | 10 | 李四 | 22 | 财务 | 二组 | | 3 | 25 | 赵六 | 24 | 财务 | 一组 |

| | 利润 | 年龄 | | ---- | ---- | ---- | | 部门 | | | | 研发 | 15 | 43 | | 财务 | 35 | 46 |

In [108]:

df = pd.DataFrame({'部门':['研发','财务','研发','财务'],'项目组':['一组','二组','二组','一组'],
                   '姓名':['张三','李四','王五','赵六'],'年龄':[20,22,23,24],'利润':[5,10,10,25]})
# display(df)

group= df.groupby('部门')
for k,v in group:
    display(k,v)

# 使用mean sum这些统计方法得到聚合信息
# display(df.mean(numeric_only=True),df.sum(numeric_only=True))

# agg方法实现对DataFrame、分组对象的聚合,可以传入4种类参数,字符串、列表、字典以及函数
# 1 字符串
# display(df.agg('mean',numeric_only=True),df.agg('sum',numeric_only=True))
# 2 多个字符串构成的列表
# 优点,可以将mean和sum2个聚合信息合并起来展示
# display(df.agg(['mean','sum']))
# 3 字典  {k1:v1,k2:v2}  k 指定索引名称,value 指定统计函数名
# 针对不同的列,提供不同统计聚合方法
# display(df.agg({'利润':['mean','sum'],'年龄':['max','min']}))
# 4 函数 
# 自定义聚合方式,函数具有一个参数,用来DateFrame传递过每一列(行),返回操作后结果
# display(df.agg(lambda x:display(x,type(x))))
# display(df.agg(lambda x:x.mean() if x.name=='利润' else None))


# agg方法实现对分组对象的聚合
# 字符串
# display(group.agg('mean'))
# 列表
# display(group.agg(['mean','sum']))
# 字典
# display(group.agg({'利润':['mean','sum'],'年龄':['max','min']}))
# 函数
# 函数的参数是分组后得到的DataFrame的每列的数据
# display(group.agg(lambda x:display(x,type(x))))
display(group.agg(lambda x:x.mean() if x.name=='利润' else None))
'研发'

| | 利润 | 姓名 | 年龄 | 部门 | 项目组 | | ---- | ---- | ---- | ---- | ---- | ------ | | 0 | 5 | 张三 | 20 | 研发 | 一组 | | 2 | 10 | 王五 | 23 | 研发 | 二组 |

'财务'

| | 利润 | 姓名 | 年龄 | 部门 | 项目组 | | ---- | ---- | ---- | ---- | ---- | ------ | | 1 | 10 | 李四 | 22 | 财务 | 二组 | | 3 | 25 | 赵六 | 24 | 财务 | 一组 |

| | 利润 | 姓名 | 年龄 | 项目组 | | ---- | ---- | ---- | ---- | ------ | | 部门 | | | | | | 研发 | 7.5 | None | None | None | | 财务 | 17.5 | None | None | None |

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值