pandas:层次化索引

层次化索引(hierarchical indexing)是pandas的一个重要的功能,它可以在一个轴上有多个(两个以上)的索引,这就表示着,它能够以低维度形式来表示高维度的数据。

一. 创建多层行索引

1、 隐式构造

1)最常见的方法是给DataFrame构造函数的index参数传递两个或更多的数组,Series也可以创建多层索引。
s = Series(np.random.randint(0,150,size=10),index=list('qwertyuiop'))
print(s)
'''
q     63
w     71
e     80
r     78
t      9
y     27
u    107
i      1
o     68
p     69
dtype: int32
'''
s = Series(np.random.randint(0,150,size=6),
           index=[['a','a','b','b','c','c'],
                  ['期中','期末','期中','期末','期中','期末']])

print(s)
'''
a  期中     16
   期末     93
b  期中    149
   期末      6
c  期中     86
   期末     52
dtype: int32
'''


df = DataFrame(s,columns=['python'])
print(df)
'''
      python
a 期中     140
  期末      91
b 期中     101
  期末      37
c 期中       1
  期末      47
'''
2)DataFrame建立2级列索引
df1 = DataFrame(np.random.randint(0,150,size=(4,6)),
               index = list('东南西北'),
               columns=[['python','python','math','math','En','En'],
                        ['期中','期末','期中','期末','期中','期末']])

print(df1)
'''
  python      math        En     
      期中   期末   期中   期末   期中   期末
东    143  107   33  107   86  117
南      8  147    5   35  106   23
西    115  124   77   76   39   30
北     27  141  126   50   70   88
'''

2、 显示构造pd.MultiIndex

1)使用数组构造
df2 = DataFrame(np.random.randint(0,150,size=(4,6)),
               index = list('东南西北'),
               columns=[['python','python','math','math','En','En'],
                        ['期中','期末','期中','期末','期中','期末']])

print(df2)
'''
  python     math       En     
      期中  期末   期中  期末   期中   期末
东     99  51  144  65   36  147
南     18  65    2  59  125  107
西     50  61  131  85   40  118
北     82  31  106  21   75  129
'''
2)使用tuple构造
df3 = DataFrame(np.random.randint(0,150,size=(4,6)),
               index = list('东南西北'),
               columns =pd.MultiIndex.from_tuples([('python','期中'),('python','期末'),                                                   
                                                  ('math','期中'),('math','期末'),
                                                  ('En','期中'),('En','期末')]))
'''
  python      math        En     
      期中   期末   期中   期末   期中   期末
东    129  122   32   17   93   35
南     89  125   73  112   10  140
西     23   65   84    8   24  144
北    136  127  119  147  122  136
'''
3)使用product构造(推荐)
df4 = DataFrame(np.random.randint(0,150,size=(8,12)),
               columns = pd.MultiIndex.from_product([['模拟考','正式考'],
                                                   ['数学','语文','英语','物理','化学','生物']]),
               index = pd.MultiIndex.from_product([['期中','期末'],
                                                   ['雷军','李斌'],
                                                  ['测试一','测试二']]))
print(df4)
'''
                 模拟考                          正式考                         
                   数学 语文 英语 物理 化学 生物   数学 语文 英语 物理 化学 生物
期中 雷军 测试一      8  116    5  110  135   73     65   50  123  103   50   83
          测试二    146  118   17  137  113   69    103   76  146   24   63  127
     李斌 测试一    142  122  104   39   35   66     56  107    7  133   73  111
          测试二     45   43   10   43  118   90    106   45   35   43   22  127
期末 雷军 测试一     66   26  133   84   42  109    101  100   52  125  118  115
          测试二     96   55   29   39   95  122    124   62   90   46  101  103
     李斌 测试一      5  109  123   18  102  106    129    8   97  123  147   75
          测试二    122   32    1   15  119    0     60  149    3  135   13   20
'''

二. 多层索引对象的索引与切片操作

1、Series的操作

注意:对于Series来说,直接中括号[]与使用.loc()完全一样,推荐使用中括号索引和切片

s = Series(np.random.randint(0,150,size=6),
           index=[['a','a','b','b','c','c'],
                  ['期中','期末','期中','期末','期中','期末']])
print(s)

# 输出
a  期中    59
   期末    43
b  期中    28
   期末    99
c  期中    92
   期末    58
dtype: int32
s['a','期中']
# 输出
59
s[['a','b']]   #取多层的外层索引时,内层索引不可用
#输出
a  期中    59
   期末    43
b  期中    28
   期末    99
dtype: int32
s['a'][['期中','期末']]['期中']
# 输出
59
s.loc['a']
# 输出
期中    59
期末    43
dtype: int32
s.iloc[:5]   #iloc计算的是最内层索引
# 输出
a  期中    59
   期末    43
b  期中    28
   期末    99
c  期中    92
dtype: int32

2、DataFrame操作

(1) 可以直接使用列名称来进行列索引
(2) 使用行索引需要用ix()loc()等函数

推荐使用loc()函数
注意:在对行索引的时候,若一级行索引还有多个,对二级行索引会遇到问题!也就是说,无法直接对二级索引进行索引,必须让二级索引变成一级索引后才能对其进行索引!

df4 = DataFrame(np.random.randint(0,150,size=(8,12)),
               columns = pd.MultiIndex.from_product([['模拟考','正式考'],
                                                   ['数学','语文','英语','物理','化学','生物']]),
               index = pd.MultiIndex.from_product([['期中','期末'],
                                                   ['雷军','李斌'],
                                                  ['测试一','测试二']]))

在这里插入图片描述

df4['模拟考'][['语文','数学']]

在这里插入图片描述

df4.loc['期中','雷军','测试一']['模拟考','数学']
# 输出
61
df4.loc['期中','雷军','测试一']
# 输出
模拟考  数学     61
     语文     90
     英语     97
     物理      6
     化学    118
     生物    127
正式考  数学    143
     语文     35
     英语     79
     物理      4
     化学     90
     生物     54
Name: (期中, 雷军, 测试一), dtype: int32
df4.iloc[0]   #iloc是只取最内层的索引的
模拟考  数学     61
     语文     90
     英语     97
     物理      6
     化学    118
     生物    127
正式考  数学    143
     语文     35
     英语     79
     物理      4
     化学     90
     生物     54
Name: (期中, 雷军, 测试一), dtype: int32
df4['正式考']

在这里插入图片描述
注意:列索引从列开始取,必须一层层取,取完列索引,才可以取行索引,先取行索引同理。

三、重排分级顺序

在使用层次化索引的时候,我们可以重新调整某条轴上各级别的顺序,或根据级别上的值对数据进行排序。swaplevel接受两个级别编号或名称,返回一个互换了级别的新对象(数据不变)。我们可以对每个级别设置一个名称,就像对DataFrame设置行列索引的名称一样。

    data = DataFrame(np.arange(12).reshape(4,3),
                     index=[["a","a","b","b"],[1,2,1,2]],
                     columns=[["A","A","B"],["Z","X","C"]])
    print(data)
    '''
         A       B
         Z   X   C
    a 1  0   1   2
      2  3   4   5
    b 1  6   7   8
      2  9  10  11
    '''
    #对每一个级别设置一个名称
    #设置行级别的名称
    data.index.names=["row1","row2"]
    #设置列级别的名称
    data.columns.names=["column1","column2"]
    print(data)
    '''
    column1    A       B
    column2    Z   X   C
    row1 row2
    a    1     0   1   2
         2     3   4   5
    b    1     6   7   8
         2     9  10  11
    '''
    #通过swaplevel,调整行的顺序
    print(data.swaplevel("row1","row2"))
    '''
    column1    A       B
    column2    Z   X   C
    row2 row1
    1    a     0   1   2
    2    a     3   4   5
    1    b     6   7   8
    2    b     9  10  11
    '''
    #对指定级别中的值进行排序
    #对级别名称为row2中的值进行排序
    print(data.sortlevel(1))#等价于data.swaplevel(0,1).sortlevel(0)
    '''
    column1    A       B
    column2    Z   X   C
    row1 row2           
    a    1     0   1   2
    b    1     6   7   8
    a    2     3   4   5
    b    2     9  10  11
    '''

四、根据级别汇总统计

    data = DataFrame(np.arange(12).reshape(4,3),
                     index=[["a","a","b","b"],[1,2,1,2]],
                     columns=[["A","A","B"],["Z","X","C"]])
    print(data)
    '''
         A       B
         Z   X   C
    a 1  0   1   2
      2  3   4   5
    b 1  6   7   8
      2  9  10  11
    '''
    #对每一个级别设置一个名称
    #设置行级别的名称
    data.index.names=["row1","row2"]
    #设置列级别的名称
    data.columns.names=["column1","column2"]
    print(data)
    '''
    column1    A       B
    column2    Z   X   C
    row1 row2
    a    1     0   1   2
         2     3   4   5
    b    1     6   7   8
         2     9  10  11
    '''
    #指定行级别的名称进行求和
    print(data.sum(level="row1"))
    '''
    column1   A       B
    column2   Z   X   C
    row1
    a         3   5   7
    b        15  17  19
    '''
    #指定列级别的名称进求和
    print(data.sum(level="column1",axis=1))
    '''
    column1     A   B
    row1 row2        
    a    1      1   2
         2      7   5
    b    1     13   8
         2     19  11
    '''
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
DataFrame的层次化索引是指在DataFrame中的行或列上使用多个索引级别来表示数据的一种结构。这种索引结构可以让我们在一个轴上拥有多个索引级别。 在构建DataFrame的层次化索引时,可以通过多种方法实现。一种方法是在导入数据时直接使用列名作为行索引,使用`index_col`参数来指定多个列作为索引。另一种方法是使用`set_index()`方法将某几列设置为索引。设置索引后,可以选择是否保留原始列作为DataFrame的一部分。而要将层次化索引转换为二维表格形式,可以使用`reset_index()`函数。 除了以上方法,还可以在创建DataFrame时直接指定多级索引,可以通过使用一个由列表或数组组成的列表作为索引来实现。例如,可以使用`pd.DataFrame()`函数的`index`参数来指定多级索引的值。 综上所述,DataFrame的层次化索引可以通过在导入数据时设置索引列,使用`set_index()`方法或在创建DataFrame时直接指定多级索引来实现。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Python学习笔记8——Series与DataFrame中的层次化索引](https://blog.csdn.net/weixin_44181744/article/details/105977700)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [pandas 层次化索引的实现方法](https://download.csdn.net/download/weixin_38679651/14914102)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值