求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
要资料
 
追随技术信仰

随时听讲座
每天看新闻
 
 
Pandas 教程
1. Pandas 是什么
2.Pandas库下载和安装
3.Pandas Series入门教程
4.Pandas DataFrame入门教程
5.Pandas Panel三维数据结构
6.Python Pandas描述性统计
7.Pandas使用自定义函数
8.Pandas reindex重置索引
9.Pandas iteration遍历
10.Pandas sorting排序
11.Pandas去重函数:drop_duplicates()
12.Python Pandas处理字符串(方法详解)
13.Pandas设置数据显示格式
14.Pandas loc/iloc用法详解
15.Python Pandas统计函数
16.Python Pandas窗口函数
17.Python Pandas聚合函数
18.Python Pandas缺失值处理
19.Pandas groupby分组操作详解
20.Pandas merge合并操作
21.Pandas concat连接操作
22.Python Pandas时间序列
23.Pandas日期时间格式化
24.Padans Timedelta时间差
25.Pandas随机选择样本
26.Pandas数据重采样
27.Python Pandas分类对象
28.Python Pandas绘图
29.Python Pandas读取文件
30.Pandas csv读写文件
31.Pandas Excel读写操作
32.Pandas index操作索引
33.Pandas分层索引入门教程
34.Pandas执行SQL操作
35.Pandas和NumPy的比较
36.Pandas使用的注意事项
 

 
Pandas分层索引入门教程(详解)
94 次浏览
3次  

分层索引(Multiple Index)是 Pandas 中非常重要的索引类型,它指的是在一个轴上拥有多个(即两个以上)索引层数,这使得我们可以用低维度的结构来处理更高维的数据。比如,当想要处理三维及以上的高维数据时,就需要用到分层索引。

分层索引的目的是用低维度的结构(Series 或者 DataFrame)更好地处理高维数据。通过分层索引,我们可以像处理二维数据一样,处理三维及以上的数据。分层索引的存在使得分析高维数据变得简单,让抽象的高维数据变得容易理解,同时它比废弃的 Panel 结构更容易使用。

Pandas 可以通过 MultiIndex() 方法来创建分层索引对象,该对象本质上是一个元组序列,序列中每一个元组都是唯一的。下面介绍几种创建分层索引的方式。


创建分层索引

1) 直接创建

通过 MultiIndex() 的 levels 参数能够直接创建分层索引,示例如下:

1.import pandas as pd 
2. import numpy as np
3. #为leves传递一个1行5列的二维数组
4. df=pd.MultiIndex(levels=[[np.nan, 2, pd.NaT, None, 5]], codes=[[4, -1, 1, 2, 3, 4]])
5. print(df.levels)
6. print(df)

输出结果:

[[nan, 2, NaT, None, 5]]

MultiIndex([(  5,),
            (nan,),
            (  2,),
            (nan,),
            (nan,),
            (  5,)],
           )

上述代码中, levels 参数用来创建层级索引,这里只有一层,该层的索引值分别是 np.nan, 2, NaT, None, 5; codes 表示按参数值对层级索引值排序(与 levels 中的值相对应),也就说 codes 中数值是 leves 序列的下标索引。需要注意,这里的 -1 代表 NaN。

2) 从元组创建

通过 from_tuples() 实现从元组创建分层索引。

1.#创建元组序列
2. arrays = [['it', 'it', 'of', 'of', 'for', 'for', 'then', 'then'],
3. ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]
4. #使用zip()函数创建元组
5. tuples = list(zip(*arrays))
6. print(tuples)

输出结果如下:

[('it', 'one'),
('it', 'two'),
('of', 'one'),
('of', 'two'),
('for', 'one'),
('for', 'two'),
('then', 'one'),
('then', 'two')]

然后使用 tuples 创建分层索引,如下所示:

1.import pandas as pd
2. #创建了两层索引,并使用names对它们命名
3. index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
4. print(index)

输出结果:

MultiIndex([(  'it', 'one'),
            (  'it', 'two'),
            (  'of', 'one'),
            (  'of', 'two'),
            ( 'for', 'one'),
            ( 'for', 'two'),
            ('then', 'one'),
            ('then', 'two')],
           names=['first', 'second'])

3) 从DataFrame对象创建

通过 from_frame() 创建分层索引,示例如下:

1.#首先创建一个 DataFrame。
2. import pandas as pd
3. df = pd.DataFrame([['bar', 'one'], ['bar', 'two'],
4. ['foo', 'one'], ['foo', 'two']],
5. columns=['first', 'second'])
6. #然后使用 from_frame()创建分层索引。
7. index = pd.MultiIndex.from_frame(df)
8. #将index应用于Series
9. s=pd.Series(np.random.randn(4), index=index)
10. print(s)

输出结果:

first  second
bar    one       1.151928
       two      -0.694435
foo    one      -1.701611
       two      -0.486157
dtype: float64

4) 笛卡尔积创建

笛卡尔积(又称直积)是数学运算的一种方式,下面使用 from_product() 笛卡尔积创建分层索引。

1.import pandas as pd
2. #构建数据
3. numbers = [0, 1, 2]
4. language = ['Python', 'Java']
5. #经过笛卡尔积处理后会得到6中组合方式
6. index = pd.MultiIndex.from_product([numbers, language],names=['number', 'language'])
7. #将分层索引对象应用于Series
8. dk_er=pd.Series(np.random.randn(6), index=index)
9. print(dk_er)

输出结果:

number  language
0       Python     -0.319739
        Java        1.599170
1       Python     -0.010520
        Java        0.262068
2       Python     -0.124177
        Java        0.315120
dtype: float64

5) 数组创建分层索引

通过 from_array() 方法,同样可以创建分层索引。示例如下:

1.import pandas as pd
2. df=pd.MultiIndex.from_arrays([['a', 'a', 'b', 'b'],[1, 2, 1, 2]])
3. df

输出结果:

MultiIndex([('a', 1),
            ('a', 2),
            ('b', 1),
            ('b', 2)],
           )

应用分层索引

下面示例讲解了如何在 DataFrame 中应用分层索引。

1.import pandas as pd 
2. import numpy as np
3. #创建一个数组
4. arrays = [[0, 0, 1, 1], ['A', 'B', 'A', 'B']]
5. #从数组创建
6. index=pd.MultiIndex.from_arrays(arrays, names=('number', 'letter'))
7. print(index)

输出结果

MultiIndex([(0, 'A'),
            (0, 'B'),
            (1, 'A'),
            (1, 'B')],
           names=['number', 'letter'])

下面把已经创建的分层索引应用到 DataFrame 中,如下所示:

1.import pandas as pd 
2. import numpy as np
3. #创建一个数组
4. arrays = [[0, 0, 1, 1], ['A', 'B', 'A', 'B']]
5. index=pd.MultiIndex.from_arrays(arrays, names=('number', 'letter'))
6. #在行索引位置应用分层索引
7. df=pd.DataFrame([{'a':11, 'b':22}], index=index)
8. print(df)

输出结果:

                a   b
number letter       
0      A       11  22
       B       11  22
1      A       11  22
       B       11  22

通过 set_index() 可以将 DataFrame 的已有列的标索设置为 index 行索引,示例如下:

1.import pandas as pd
2. df= pd.DataFrame({'a': range(5), 'b': range(5, 0, -1),
3. 'c': ['one', 'one', 'one', 'two', 'two'],
4. 'd': [0, 1, 2, 0, 1]})
5. print(df)
6. df1=df.set_index(['a','d'],drop=False)
7. print(df1)
8. df1=df.set_index(['a','d'],drop=False,append=Ture)
9. print(df2)

输出结果:

转换前:
   a  b    c  d
0  0  5  one  0
1  1  4  one  1
2  2  3  one  2
3  3  2  two  0
4  4  1  two  1
转换后:
     a  b    c  d
a d             
0 0  0  5  one  0
1 1  1  4  one  1
2 2  2  3  one  2
3 0  3  2  two  0
4 1  4  1  two  1
带append参数:
       a  b    c  d
  a d            
0 0 0  0  5  one  0
1 1 1  1  4  one  1
2 2 2  2  3  one  2
3 3 0  3  2  two  0
4 4 1  4  1  two  1

通过 set_index() 将列索引转换为了分层行索引,其中 drop=False 表示更新索引的同时,不删除 a、d 列;同时,该函数还提供了一个 append = Ture 参数表示不添加默认的整数索引值(0到4)


分层索引切片取值

下面讲解分层索引切片取值操作,示例如下:

1) 分层行索引操作

1.import pandas as pd
2. #构建多层索引
3. tuple = [('湖人',2008),('步行者',2008),
4. ('湖人',2007),('凯尔特人',2007),
5. ('篮网',2007),('热火',2008)]
6. salary = [10000,20000,11000,30000,19000,22000]
7. #其次应用于DataFrame
8. index = pd.MultiIndex.from_tuples(tuple)
9. s = pd.Series(salary, index=index)
10. print(s)
11. #切片取值
12. print(s['湖人',2007])
13. print(s['湖人'])
14. print(s[:,2008])
15. #比较value
16. print(s[s<=20000])

输出结果:

湖人    2008    10000
步行者   2008    20000
湖人    2007    11000
凯尔特人  2007    30000
篮网    2007    19000
热火    2008    22000
dtype: int64

湖人队2007年工资:
11000

湖人队的工资:
2008    10000
2007    11000
dtype: int64

2008年所有队伍工资:
湖人     10000
步行者    20000
热火     22000
dtype: int64

小于等于20000的年份和队伍:
湖人   2008    10000
步行者  2008    20000
湖人   2007    11000
篮网   2007    19000
dtype: int64

2) 行、列多层索引操作

下面看一种更加复杂的情况,就是行、列同时存在多层索引时候,应该如何通过切片取值。示例如下:

1.df = pd.DataFrame(np.arange(1,13).reshape((4, 3)),
2. index=[['a', 'a', 'b', 'b'], [1, 2, 1, 2]],
3. columns=[['Jack', 'Jack', 'Helen'],
4. ['Python', 'Java', 'Python']])
5. #选择同一层级的索引,切记不要写成['Jack','Helen']
6. print(df[['Jack','Helen']])
7. #在不同层级分别选择索引
8. print(df['Jack','Python'])
9. #iloc整数索引
10. print(df.iloc[:3,:2])
11. #loc列标签索引
12. print(df.loc[:,('Helen','Python')])

输出结果:

      Jack       Helen
    Python Java Python
a 1      1    2      3
  2      4    5      6
b 1      7    8      9
  2     10   11     12

a  1     1
   2     4
b  1     7
   2    10
Name: (Jack, Python), dtype: int32

      Jack    
    Python Java
a 1      1    2
  2      4    5
b 1      7    8

a  1     3
   2     6
b  1     9
   2    12
Name: (Helen, Python), dtype: int32

聚合函数应用

通过给 level 传递参数值,您可以指定在哪个层上进行聚合操作,比如求和、求均值等。示例如下:

1.import pandas as pd 
2. df = pd.DataFrame(np.arange(1,13).reshape((4, 3)),
3. index=[['a', 'a', 'b', 'b'], [1, 2, 1, 2]],
4. columns=[['Jack', 'Jack', 'Helen'],
5. ['Python', 'Java', 'Python']])
6. #第一步,给行列层级起名字
7. df.index.names=['key1','key2']
8. df.columns.names=['name','course']
9. print(df.sum(level='key2'))
10. print(df.mean(level="course",axis=1))

输出结果:

#对key2层1/2对应的元素值求和
name     Jack       Helen
course Python Java Python
key2                    
1           8   10     12
2          14   16     18

#axis=1沿着水平方向求均值
course     Python  Java
key1 key2             
a    1          2     2
     2          5     5
b    1          8     8
     2         11    11

在数据分析的过程中,我们把大部分时间都花费在数据的准备和预处理上,Pandas 作为一个灵活、高效的数据预处理工具,提供了诸多数据处理的方法,分层索引(Multiple Index)就是其中之一,分层索引(或多层索引)是 Pandas 的基本特性,它能够增强 Pands 数据预处理的能力。

对于 Series 结构来说,通过给 index 参数传递一个二维数组就可以创建一个具有两层索引的 MultiIndex 对象,示例如下:

1.import pandas as pd 
2. info = pd.Series([11, 14, 17, 24, 19, 32, 34, 27],
3. index = [['x', 'x', 'x', 'x', 'y', 'y', 'y', 'y'],
4. ['obj1', 'obj2', 'obj3', 'obj4', 'obj1', 'obj2', 'obj3', 'obj4']])
5. print(info)

输出结果:

x  obj1    11
   obj2    14
   obj3    17
   obj4    24
y  obj1    19
   obj2    32
   obj3    34
   obj4    27
dtype: int64

上述示例,创建了两个层级的索引,即 (x, y) 和 (obj1,…, obj4),您可以使用 'index' 命令查看索引。

info.index

输出结果:

MultiIndex([('x', 'obj1'),
            ('x', 'obj2'),
            ('x', 'obj3'),
            ('x', 'obj4'),
            ('y', 'obj1'),
            ('y', 'obj2'),
            ('y', 'obj3'),
            ('y', 'obj4')],
           )

此外,您还可以基于内部索引层(也就是'obj')来选择数据。如下所示:

info [:,'obj2' ]

输出结果:

x    14
y    32
dtype: int64

局部索引

局部索引可以理解为:从分层索引中选择特定索引层的一种方法。比如在下列数据中,选择所有 'y' 索引指定的数据,示例如下:

1.import pandas as pd 
2. info = pd.Series([11, 14, 17, 24, 19, 32, 34, 27],
3. index = [['x', 'x', 'x', 'x', 'y', 'y', 'y', 'y'],
4. ['obj1', 'obj2', 'obj3', 'obj4', 'obj1', 'obj2', 'obj3', 'obj4']])
5. info['y']

输出结果:

obj1    19
obj2    32
obj3    34
obj4    27
dtype: int64

当然您也可以基于内层索引选择数据。


行索引层转换为列索引

unstack() 用来将行索引转变成列索引,相当于转置操作。通过 unstack() 可以将 Series(一维序列)转变为 DataFrame(二维序列)。示例如下:

1.import pandas as pd 
2. info = pd.Series([11, 14, 17, 24, 19, 32, 34, 27],
3. index = [['x', 'x', 'x', 'x', 'y', 'y', 'y', 'y'],
4. ['obj1', 'obj2', 'obj3', 'obj4', 'obj1', 'obj2', 'obj3', 'obj4']])
5. #行索引标签默认是最外层的 x, y
6. #0代表第一层索引,而1代表第二层
7. print(info.unstack(0))

输出结果:

1.       x   y
2. obj1 11 19
3. obj2 14 32
4. obj3 17 34
5. obj4 24 27

从示例可以看出,unstack(0) 表示选择第一层索引作为列,unstack(1) 表示选择第二层,如下所示:

1.import pandas as pd 
2. info = pd.Series([11, 14, 17, 24, 19, 32, 34, 27],
3. index = [['x', 'x', 'x', 'x', 'y', 'y', 'y', 'y'],
4. ['obj1', 'obj2', 'obj3', 'obj4', 'obj1', 'obj2', 'obj3', 'obj4']])
5. print(info.unstack(1))

输出结果:

   obj1  obj2  obj3  obj4
x    11    14    17    24
y    19    32    34    27

列索引实现分层

我们知道,列索引存在于 DataFrame 结构中,下面创建一个 DataFrame 来演示列索引如何实现分层。

1.import numpy as np  
2. info = pd.DataFrame(np.arange(12).reshape(4, 3),
3. index = [['a', 'a', 'b', 'b'], ['one', 'two', 'three', 'four']],
4. columns = [['num1', 'num2', 'num3'], ['x', 'y', 'x']] )
5. print(info)

输出结果:

        num1 num2 num3
           x    y    x
a one      0    1    2
  two      3    4    5
b three    6    7    8
  four     9   10   11

查看所有列索引:

info.columns

输出结果:

MultiIndex([('num1', 'x'),
            ('num2', 'y'),
            ('num3', 'x')],)

交换层和层排序

1) 交换层

通过 swaplevel() 方法轻松地实现索引层交换,示例如下:

1.import pandas as pd
2. frame = pd.DataFrame(np.arange(12).reshape((4, 3)),
3. index=[['a', 'a', 'b', 'b'], [1, 2, 1, 2]],
4. columns=[['Ohio', 'Ohio', 'Colorado'],
5. ['Green', 'Red', 'Green']])
6. #设置index的levels名称
7. frame.index.names = ['key1', 'key2']
8. #设置columns的levels名称
9. frame.columns.names = ['state','color']
10. #交换key1层与key层
11. frame.swaplevel('key1','key2')

输出结果:

state      Ohio     Colorado
color     Green Red    Green
key2 key1                  
1    a        0   1        2
2    a        3   4        5
1    b        6   7        8
2    b        9  10       11

2) 层排序

通过 sort_index() 的 level 参数实现对层的排序。下面示例,按“key1”的字母顺序重新排序。

1.import pandas as pd
2. frame = pd.DataFrame(np.arange(12).reshape((4, 3)),
3. index=[['a', 'a', 'b', 'b'], [1, 2, 1, 2]],
4. columns=[['Ohio', 'Ohio', 'Colorado'],
5. ['Green', 'Red', 'Green']])
6. #设置index的levels的名称,key1 与 key2分别对应不同的层
7. frame.index.names = ['key1', 'key2']
8. #设置columns的levels的名称
9. frame.columns.names = ['state','color']
10.  
11. print(frame.sort_index(level='key1'))

输出结果:

state      Ohio     Colorado
color     Green Red    Green
key1 key2                  
a    1        0   1        2
     2        3   4        5
b    1        6   7        8
     2        9  10       11

您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码: 验证码,看不清楚?请点击刷新验证码 必填



94 次浏览
3次