• 多层索引MultiIndex


    深入浅出Pandas读书笔记

    C8 Pandas多层索引

    使你在Series和DataFrame中存储和处理更高维度的数据

    8.1 概述

    8.1.1 什么是多层索引

    8.1.2 通过分组产生多层索引

    # 按团队分组, 各团队中平均成绩及格的人数
    df.groupby(['team', df.select_dtypes('number').mean(1)>60]).count()
    # 在列上产生多级索引
    df.groupby('team').agg([min, max])
    
    • 1
    • 2
    • 3
    • 4

    8.1.3 由序列创建多级索引

    MultiIndex对象是Pandas标准Index的子类, 由他来表示多层索引业务. 可以将MultiIndex视为一个元祖对序列, 其中每个元祖对都是唯一的

    # 定义一个序列, 生成多级索引
    arrays = [[1, 1, 2, 2], ['A', 'B']*2]
    index = pd.MultiIndex.from_arrays(arrays, names=['class', 'team'])
    index     
    '''
    MultiIndex([(1, 'A'),
                (1, 'B'),
                (2, 'A'),
                (2, 'B')],
               names=['class', 'team'])
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    8.1.4 由元祖创建多层索引

    使用pd.MultiIndex.from_tuples()将由元祖组成的序列转换为多层索引

    arrays = [[1, 1, 2, 2], ['A', 'B']*2]
    tuples = list(zip(*arrays))
    index = pd.MultiIndex.from_tuples(tuples, name=['class', 'team'])
    pd.Series(np.random.randn(4), index=index)
    '''
    class  team
    1      A       1.013703
           B      -1.184143
    2      A       0.870257
           B       0.893465
    dtype: float64
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    8.1.5 可迭代对象的笛卡尔积

    pd.MultiIndex.from_product()可以做笛卡尔积计算

    _class = [1, 2]
    team = ['A', 'B']
    index = pd.MultiIndex.from_product([_class, team], names=['class', 'team'])
    index
    '''
    MultiIndex([(1, 'A'),
                (1, 'B'),
                (2, 'A'),
                (2, 'B')],
               names=['class', 'team'])
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    8.1.6 将DataFrame转为多层索引对象

    pd.MultiIndex.from_frame()可以将DataFrame的数据转为多层索引对象

    df_i = pd.DataFrame([['1', 'A'], ['1', 'B'], ['2', 'B'], ['2', 'B']], columns=['class', 'name'])
    index = pd.MultiIndex.from_frame(df_i)
    index
    
    • 1
    • 2
    • 3

    8.2 多层索引操作

    8.2.1 生成数据

    index_arrays = [[1, 1, 2, 2,], ['男', '男', '女', '女']]
    columns_arrays = [['2019', '2019', '2020', '2020'], ['上半年', '下半年']*2]
    index = pd.MultiIndex.from_arrays(index_arrays, names=('班级', '性别'))
    columns = pd.MultiIndex.from_arrays(columns_arrays, names=('年份', '学期'))
    df = pd.DataFrame([[88, 99, 88, 99], [77, 88, 97, 98], [67, 89, 54, 78], [34, 67, 89, 54]],
                      columns=columns, index=index)
    df
    '''
    	年份	2019	2020
    学期	上半年	下半年	上半年	下半年
    班级	性别				
    1	男	88	99	88	99
    男	77	88	97	98
    2	女	67	89	54	78
    女	34	67	89	54
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    8.2.2 索引信息

    df.index
    '''
    MultiIndex([(1, '男'),
                (1, '男'),
                (2, '女'),
                (2, '女')],
               names=['班级', '性别'])
    '''
    MultiIndex([(1, '男'),
                (1, '男'),
                (2, '女'),
                (2, '女')],
               names=['班级', '性别'])
    '''
    MultiIndex([('2019', '上半年'),
                ('2019', '下半年'),
                ('2020', '上半年'),
                ('2020', '下半年')],
               names=['年份', '学期'])
    '''
    df.index.names # FrozenList(['班级', '性别'])
    df.columns.names # FrozenList(['年份', '学期'])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    8.2.3 查看层级

    df.index.nlevels # 行层级数
    df.index.levels # 行层级
    df.columns.nlevels # 列层级数
    df.columns.levels # 列层级
    
    • 1
    • 2
    • 3
    • 4

    8.2.4 索引内容

    # 获取索引第二层内容
    df.index.get_level_values(1)
    # 获取列索引第一层内容
    df.columns.get_level_values(0)
    # 按索引名称取索引内容
    df.index.get_level_values('班级')
    df.columns.get_level_values('年份')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    8.2.5 排序

    df.sort_values(by=['性别', ('2020', '下半年')])
    df.index.reorder_levels([1, 0]) # 等级顺序, 互换
    df.swaplevel() # 等同于上面
    
    • 1
    • 2
    • 3

    8.2.6 其他操作

    df.index.to_numpy() # 横撑一个笛卡尔积的元祖对序列
    df.swaplevel()
    df.index.droplevel(0) # 删除指定等级
    
    • 1
    • 2
    • 3

    8.3 数据查询

    8.3.1 查询行

    df.loc[1]
    df.loc[(1, '男')]
    
    • 1
    • 2

    8.3.2 查询列

    df[‘2020’] # 整个一级索引
    df[(‘2020’, ‘上半年’)] # 指定二级索引
    df[‘2020’][‘上半年’] # 同上

    8.3.3 行列查询

    行列查询和单层索引一样, 指定层内容也用元祖表示. slice(None)可以在元组中占位, 表示本层所有内容

    df.loc[(1, '男'), '2020']
    df.loc[:, (slice(None), '下半年')] # 只看下半年
    df.loc[(slice(None), '女'), :] # 只看女生
    df.loc[(1, slice(None)), :] # 只看1班
    df.loc[:, ('2020', slice(None))] # 只看2020年数据
    
    • 1
    • 2
    • 3
    • 4
    • 5

    8.3.4 条件查询

    df[df[('2020', '上半年')] > 80]
    
    • 1

    8.3.5 用pd.IndexSlice索引数据

    8.3.6 df.xs()

    若找的是level=0的数据, 不需要指定level, 找其他层需要传入level=第几层, 找columns, 需要指定axis=1

    df.xs((1, '男')) # 1班男生
    df.xs('2020', axis=1) # 2020年
    df.xs('男', level=1) # 所有男生
    df.xs(2) # 所有2班的数据
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    MYSQL round()函数
    HashMap
    Spring Boot框架中的@Conditional系列注解
    redis企业级数据备份方案以及数据恢复
    第六节.常用Linux命令—chmod修改目录权限,组管理,用户管理
    化工厂4G+蓝牙+GPS/北斗RTK人员定位系统解决方案
    git 使用
    makefile目标规则
    部署云MYSQL(在线版)
    linux系统nginx常用命令
  • 原文地址:https://blog.csdn.net/zhaoleiedu/article/details/127762306