Pandas进阶之DataFrame多级索引

  多级索引:在一个轴上有多个(两个以上)的索引,能够以低维度形式来表示高维度的数据。单级索引是Index对象,多级索引是MultiIndex对象。

一、创建多级索引

  • 方法一:隐式创建,即给DataFrame的indexcolumns参数传递两个或更多的数组。
    df1 = pd.DataFrame(np.random.randint(80, 120, size=(2, 4)),
                       index= ['girl', 'boy'],
                       columns=[['English', 'English', 'Chinese', 'Chinese'],
                             ['like', 'dislike', 'like', 'dislike']])
    
    print(df1)    # 创建多级 列 索引
    -------------------------------------------------------------------------------------
              English         Chinese
              like  dislike   like    dislike
        girl  85    109       117     110
        boy   85    111       100     107
    
  • 方法二、显示创建,推荐使用较简单的pd.MultiIndex.from_product方法
    df2 = pd.DataFrame(np.random.randint(80, 120, size=(4, 2)), 
                       columns= ['girl', 'boy'],
                       index=pd.MultiIndex.from_product([['English','Chinese'],
                                                        ['like','dislike']]))
    print(df2)    # 创建多级 行 索引
    -------------------------------------------------------------------------------------
                      girl    boy
    English   like    92      98
              dislike 118     99
    Chinese   like    109     108
              dislike 108     91
    

二、检索多级索引

  • 类似单级索引检索(loc、iloc),以df1数据为例
    df1.English
    -------------------------------------------------------------------------------------
          like  dislike
    girl  105   112
    boy   118   87
    
    
    df1.English.dislike
    -------------------------------------------------------------------------------------
    girl    112
    boy      87
    Name: dislike, dtype: int64
    
    
    df1.iloc[:,0:3]
    -------------------------------------------------------------------------------------
          English        Chinese
          like  dislike  like
    girl  85    113      82
    boy   97    83       94
    
    
    df1.loc['girl', ['English', 'Chinese']]
    -------------------------------------------------------------------------------------
    English  like       105
             dislike    112
    Chinese  like        87
             dislike     92
    Name: girl, dtype: int64
    
  • 多级索引的检索,可以使用更高级的方法,如xs、IndexSlice等,用到较少暂不介绍。

三、更改索引的层级

  1. 创建多级索引
    df = pd.DataFrame(np.random.randint(80, 120, size=(6, 4)), 
                  index= pd.MultiIndex.from_product([[1, 2, 3],['girl', 'boy']]),
                  columns=pd.MultiIndex.from_product([['English','Chinese'],
                                                      ['Y','N']]))
    print(df) 
    -------------------------------------------------------------------------------------
                English Chinese
                Y   N   Y   N
    1   girl    86  99  111 105
        boy     85  110 113 112
    2   girl    98  106 108 94
        boy     117 80  97  83
    3   girl    95  81  114 95
        boy     106 95  119 81
    
  2. 为多级索引命名
    df.columns.names = ['Language', 'Pass']    # 设置列索引名
    df.index.names = ['Class', 'Six']    # 设置行索引名
    
    print(df) 
    -------------------------------------------------------------------------------------
    Language        English Chinese
    Pass            Y   N   Y   N
    Class   Six             
    1       girl    86  99  111 105
            boy     85  110 113 112
    2       girl    98  106 108 94
            boy     117 80  97  83
    3       girl    95  81  114 95
            boy     106 95  119 81
    
  3. 更改索引的层级(swaplevel)
    df.swaplevel('Six','Class')    # 更改行索引的层级
    -------------------------------------------------------------------------------------
    Language    English Chinese
    Pass        Y   N   Y   N
    Six   Class             
    girl    1   86  99  111 105
    boy     1   85  110 113 112
    girl    2   98  106 108 94
    boy     2   117 80  97  83
    girl    3   95  81  114 95
    boy     3   106 95  119 81
    

四、多级索引的值排序(sort_index)

  • 方法一
    df.sort_index(level=0, axis=0, ascending=False)    # 对行索引Class的值进行降序排列
    -------------------------------------------------------------------------------------
    Language    English Chinese
    Pass            Y   N   Y   N
    Class   Six             
        3   girl    95  81  114 95
            boy     106 95  119 81
        2   girl    98  106 108 94
            boy     117 80  97  83
        1   girl    86  99  111 105
            boy     85  110 113 112
    
  • 方法二:使用sortlevel方法,从0.20.0版本开始,已经被弃用

五、多级索引汇总统计

  • 示例一
    df.sum(level=1) 或df.sum(level='Six')    # 对行索引Six进行求和
    -------------------------------------------------------------------------------------
    Language English Chinese
    Pass    Y   N   Y   N
    Six             
    girl    279 286 333 294
    boy     308 285 329 276
    
  • 示例二
    df.sum(level=0, axis=1)  或 df.sum(level='Language', axis=1)    # 对列索引Language进行求和   
    -------------------------------------------------------------------------------------
    Language    English Chinese
    Class   Six     
    1       girl  185   216
            boy   195   225
    2       girl  204   202
            boy   197   180
    3       girl  176   209
            boy   201   200
    

六、多级索引轴向转换

  • 常见的数据层次化结构:树状和表格


  • 轴向转换的函数
    1. stack() : 将行索引变成列索引,可以理解为将表格数据转换为树状数据
    2. unstack() : 将列索引变成行索引,可以理解为将树状数据转换为表格数据
    3. 两个函数互为逆函数,作用相反,用法相同。单级索引时,结果会生成一个Series;多级索引时默认转换最内层索引,也可以自定义转换的索引层级
  • 示例
      print(df)    # 数据源
      -------------------------------------------------------------------------------------
      Language        English Chinese
      Pass            Y   N   Y   N
      Class   Six             
      1       girl    86  99  111 105
              boy     85  110 113 112
      2       girl    98  106 108 94
              boy     117 80  97  83
      3       girl    95  81  114 95
              boy     106 95  119 81
    
      df.stack()    # 默认将最内层的行索引(Pass)转换为了列索引
      -------------------------------------------------------------------------------------
      Language            Chinese English
      Class   Six   Pass      
      1       girl  N       105   99
                    Y       111   86
              boy   N       112   110
                    Y       113   85
      2       girl  N       94    106
                    Y       108   98
              boy   N       83    80
                    Y       97    117
      3       girl  N       95    81
                    Y       114   95
              boy   N       81    95
                    Y       119   106
      
      df.unstack(level=0)    # 指定将列索引(Class)转化成行索引
      -------------------------------------------------------------------------------------
      Language    English             Chinese
      Pass    Y           N           Y           N
      Class   1   2   3   1   2   3   1   2   3   1   2   3
      Six                                             
      boy     85  117 106 110 80  95  113 97  119 112 83  81
      girl    86  98  95  99  106 81  111 108 114 105 94  95
    

七、多级索引转换单级索引

  • 步骤:先将多级的行索引转换为列索引,再重置列索引
  • 示例
    dt = df.stack()   # 将内层行索引()转换为列索引
    dt = dt.reset_index()   # 重置列索引
    
    print(dt)
    -------------------------------------------------------------------------------------
    Language  Class Six   Pass  Chinese English
    0           1   girl    N   105     99
    1           1   girl    Y   111     86
    2           1   boy     N   112     110
    3           1   boy     Y   113     85
    4           2   girl    N   94      106
    5           2   girl    Y   108     98
    6           2   boy     N   83      80
    7           2   boy     Y   97      117
    8           3   girl    N   95      81
    9           3   girl    Y   114     95
    10          3   boy     N   81      95
    11          3   boy     Y   119     106
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容

  • 宁夏佳宝 和她相识在漂流瓶,那是个于我无所事事的下午于她也是如此!她在漂流瓶上说了林肯公园的一首歌名好奇的回了一句...
    还是个小邓子阅读 217评论 16 0
  • Xcode真机支持组件. 每次升级Xcode可能隐含一些坑, 所以很多Developer可能还在使用旧版本的Xco...
    sasky2008阅读 715评论 0 0
  • 夢行者 2018.1.9 最近发觉表达能力的强弱与写作能力息息相关,一个人写作能力强,那他的表达能力差不...
    UP夢行者阅读 218评论 0 0
  • 今天公司来了2位总部老师就安排一起吃晚餐,晚餐老师的构成主要是各部门主管和我一个教学老师,当时叫到我时很惊讶。到了...
    文文的花期阅读 213评论 0 1
  • 八十九、福至心灵 消灾免难 道升 笔者共修的一位莲友陈龙舟居士,家住台北县中和市,早晚以驾驶幼儿园娃娃车为业。为人...
    谦与默阅读 326评论 0 0