当前位置:   article > 正文

MultiIndex DataFrame多重索引的引用方法_dataframe multiindex

dataframe multiindex

Python;Pandas;DataFrame;MultiIndex;有多重索引的DataFrame数据格式的引用方法

import pandas as pd
import numpy as np
 
se1=pd.Series(np.random.randn(4),index=[list("aabb"),[1,2,1,2]])
print(se1)
  • 1
  • 2
  • 3
  • 4
  • 5
a  1   -0.172952
   2    1.032693
b  1    0.760707
   2   -0.281595
dtype: float64
  • 1
  • 2
  • 3
  • 4
  • 5

有多重索引的Series的引用方法

print(se1['a'])
print('\r\n')
print(se1['a':'b'])
  • 1
  • 2
  • 3
1   -0.172952
2    1.032693
dtype: float64


a  1   -0.172952
   2    1.032693
b  1    0.760707
   2   -0.281595
dtype: float64
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
print(se1[:,1])
print('\r\n')
print(se1['a',1])
  • 1
  • 2
  • 3
a   -0.172952
b    0.760707
dtype: float64


-0.1729515873577343
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

DataFrame的行和列都可以是多重索引

df1=pd.DataFrame(np.arange(18).reshape(6,3),index=[list("AAABBB"),[1,2,3,1,2,3]],columns=[list("XXY"),[10,11,10]])
print(df1)
  • 1
  • 2
      X       Y
     10  11  10
A 1   0   1   2
  2   3   4   5
  3   6   7   8
B 1   9  10  11
  2  12  13  14
  3  15  16  17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

有多重索引的DataFrame的引用方法

  • 使用.loc[].iloc[]进行引用,实际上是每一层.loc[]都将原DataFrame“剥”成了较小的子集,在此基础上再次用.loc[]进行引用
  • .loc[].iloc[]的排列顺序对应多重索引的级别从高到低,每一级方括号[]内都是[行,列]的形式
    • 用这种方式进行索引,相对于下面将要提到的“元组索引”方法,运行效率很低
#根据索引名引用
print('df1.loc[\'A\',:]=')
print(df1.loc['A',:])
print('='*50)

print('df1.loc[\'A\']=')
print(df1.loc['A'])
print('='*50)

print('df1.loc[:,\'X\']=')
print(df1.loc[:,'X'])
print('='*50)

print('df1.loc[:,\'X\'].loc[10]=')
print(df1.loc[:,'X'].loc[:,10])
print('='*50)

print('df1.loc[\'A\',\'X\']=')
print(df1.loc['A','X'])
print('='*50)

print('df1.loc[\'A\',\'X\'].loc[1,10]=')
print(df1.loc['A','X'].loc[1,10])
print('='*50)

#根据行数或列数引用
print('df1.iloc[3,:]=')
print(df1.iloc[3,:])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
df1.loc['A',:]=
   X     Y
  10 11 10
1  0  1  2
2  3  4  5
3  6  7  8
==================================================
df1.loc['A']=
   X     Y
  10 11 10
1  0  1  2
2  3  4  5
3  6  7  8
==================================================
df1.loc[:,'X']=
     10  11
A 1   0   1
  2   3   4
  3   6   7
B 1   9  10
  2  12  13
  3  15  16
==================================================
df1.loc[:,'X'].loc[10]=
A  1     0
   2     3
   3     6
B  1     9
   2    12
   3    15
Name: 10, dtype: int32
==================================================
df1.loc['A','X']=
   10  11
1   0   1
2   3   4
3   6   7
==================================================
df1.loc['A','X'].loc[1,10]=
0
==================================================
df1.iloc[3,:]=
X  10     9
   11    10
Y  10    11
Name: (B, 1), dtype: int32
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

使用元组进行索引,可以一次性指定行或列的每一级索引。元组中每一级的索引名可以是变量,但不能是冒号:

  • 换句话说,元组中的每个元素都必须是某个值,而不能是“某些函数可识别的写法”
  • 1:3这种形式在Python中单独写出来是没有意义的,运行就会直接报错,与Matlab不同。Matlab中的1:3实际上是调用了linspace函数,会获得一个实在的数组输出[1,2,3]
    • 要克服这个问题,可以借助pandas.IndexSlice函数。pandas.IndexSlice的说明跟在本文最后,用来解决一个实际需求。
print('df1=\r\n')
print(df1)
print('='*50)

i=1
print('df1.loc[(\'A\',1)]=')
print(df1.loc[('A',i)])
#使用元组进行索引,可以一次性指定行或列的每一级索引
#元组中每一级的索引名可以是变量,但不能是冒号:
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
df1=

      X       Y
     10  11  10
A 1   0   1   2
  2   3   4   5
  3   6   7   8
B 1   9  10  11
  2  12  13  14
  3  15  16  17
==================================================
df1.loc[('A',1)]=
X  10    0
   11    1
Y  10    2
Name: (A, 1), dtype: int32
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

使用由元组组成的列表进行引用,可以一次性指定所有级别的行(或列)索引名,引用出若干个输出。

  • 注意这里是传入了[('A',1),('B',2)]这个列表,整句里有两层方括号
    • 对于.loc[]所需的两个输入来说,一个列表只能当作一个输入,所以记得在另一个位置加:或指定索引名
print('df1.loc[[(\'A\',1),(\'B\',2)]]=')
print(df1.loc[[('A',1),('B',2)]])
print('='*50)

print('df1.loc[[(\'A\',1),(\'B\',2)],\'X\']=')
print(df1.loc[[('A',1),('B',2)],'X'])
print('='*50)

print(df1.loc[('A',1):('B',2)])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
df1.loc[[('A',1),('B',2)]]=
      X       Y
     10  11  10
A 1   0   1   2
B 2  12  13  14
==================================================
df1.loc[[('A',1),('B',2)],'X']=
     10  11
A 1   0   1
B 2  12  13
==================================================
      X       Y
     10  11  10
A 1   0   1   2
  2   3   4   5
  3   6   7   8
B 1   9  10  11
  2  12  13  14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

使用由列表组成的元组进行引用,pandas会把几个列表中的所有元素做有序组合,然后输出每一种组合对应的引用结果

  • 对于.loc[]所需的两个输入来说,一个元组只能当作一个输入,所以记得在另一个位置加:或指定索引名
print(df1.loc[(['A','B'],[1,3]),:])
  • 1
      X       Y
     10  11  10
A 1   0   1   2
  3   6   7   8
B 1   9  10  11
  3  15  16  17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

也可以按照正常的.loc[行,列]格式引用,但每个索引位置都可以是指定了每一级索引名的元组

  • 这里元组之外没有额外的方括号(不是列表)
print('df1.loc[(\'A\',1),(\'X\',10)]=')
print(df1.loc[('A',1),('X',10)])
  • 1
  • 2
df1.loc[('A',1),('X',10)]=
0
  • 1
  • 2

实际需求:想越过第一级索引,直接得到第二级行索引名为1和3的、第二级列索引为10的数据:

  • 方法1:参考上述“由列表组成的元组”引用方法,第一级行索引位置的列表位置放入整个第一级索引的level list(通过df1.index.levels[0]获得),第二级行索引位置放入想要筛选出的索引名,列索引类似,第一级列索引的level list通过df1.columns.levels[0]获得
print(df1.loc[(df1.index.levels[0],[1,3]),(df1.columns.levels[0],[10])])
  • 1
      X   Y
     10  10
A 1   0   2
  3   6   8
B 1   9  11
  3  15  17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 方法2:用pandas.IndexSlice函数实现类似Matlab的语法,克服元组中不能写冒号:的问题
    • 这种方法的语法更自然,容易理解
idx = pd.IndexSlice
#pd.IndexSlice生成一个object,用来实现更好的多重索引切片
print(df1.loc[idx[:,[1,3]],idx[:,10]])
  • 1
  • 2
  • 3
      X   Y
     10  10
A 1   0   2
  3   6   8
B 1   9  11
  3  15  17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/153142?site
推荐阅读
相关标签
  

闽ICP备14008679号