Pandas的分层索引MultiIndex

为什么要学习分层索引MultiIndex?

  • 分层索引:在一个轴向上拥有多个索引层级,可以表达更高维度数据的形式;
  • 可以更方便的进行数据筛选,如果有序则性能更好;
  • groupby等操作的结果,如果是多KEY,结果是分层索引,需要会使用
  • 一般不需要自己创建分层索引(MultiIndex有构造函数但一般不用)

演示数据:百度、阿里巴巴、爱奇艺、京东四家公司的10天股票数据
数据来自:英为财经
https://cn.investing.com/

本次演示提纲:
一、Series的分层索引MultiIndex
二、Series有多层索引怎样筛选数据?
三、DataFrame的多层索引MultiIndex
四、DataFrame有多层索引怎样筛选数据?

import pandas as pd
%matplotlib inline
stocks = pd.read_excel('./datas/stocks/互联网公司股票.xlsx')
stocks.shape
(12, 8)
stocks.head(3)



日期

公司

收盘

开盘



交易量

涨跌幅

0

2019-10-03

BIDU

104.32

102.35

104.73

101.15

2.24

0.02

1

2019-10-02

BIDU

102.62

100.85

103.24

99.50

2.69

0.01

2

2019-10-01

BIDU

102.00

102.80

103.26

101.00

1.78

-0.01

stocks["公司"].unique()
array(['BIDU', 'BABA', 'IQ', 'JD'], dtype=object)
stocks.index
RangeIndex(start=0, stop=12, step=1)
stocks.groupby('公司')["收盘"].mean()
公司
BABA    166.80
BIDU    102.98
IQ       15.90
JD       28.35
Name: 收盘, dtype: float64

一、Series的分层索引MultiIndex

ser = stocks.groupby(['公司', '日期'])['收盘'].mean()
ser
公司    日期        
BABA  2019-10-01    165.15
      2019-10-02    165.77
      2019-10-03    169.48
BIDU  2019-10-01    102.00
      2019-10-02    102.62
      2019-10-03    104.32
IQ    2019-10-01     15.92
      2019-10-02     15.72
      2019-10-03     16.06
JD    2019-10-01     28.19
      2019-10-02     28.06
      2019-10-03     28.80
Name: 收盘, dtype: float64

多维索引中,空白的意思是:使用上面的值

ser.index
MultiIndex([('BABA', '2019-10-01'),
            ('BABA', '2019-10-02'),
            ('BABA', '2019-10-03'),
            ('BIDU', '2019-10-01'),
            ('BIDU', '2019-10-02'),
            ('BIDU', '2019-10-03'),
            (  'IQ', '2019-10-01'),
            (  'IQ', '2019-10-02'),
            (  'IQ', '2019-10-03'),
            (  'JD', '2019-10-01'),
            (  'JD', '2019-10-02'),
            (  'JD', '2019-10-03')],
           names=['公司', '日期'])
# unstack把二级索引变成列
ser.unstack()



日期

2019-10-01

2019-10-02

2019-10-03

公司

BABA

165.15

165.77

169.48

BIDU

102.00

102.62

104.32

IQ

15.92

15.72

16.06

JD

28.19

28.06

28.80

ser
公司    日期        
BABA  2019-10-01    165.15
      2019-10-02    165.77
      2019-10-03    169.48
BIDU  2019-10-01    102.00
      2019-10-02    102.62
      2019-10-03    104.32
IQ    2019-10-01     15.92
      2019-10-02     15.72
      2019-10-03     16.06
JD    2019-10-01     28.19
      2019-10-02     28.06
      2019-10-03     28.80
Name: 收盘, dtype: float64
ser.reset_index()



公司

日期

收盘

0

BABA

2019-10-01

165.15

1

BABA

2019-10-02

165.77

2

BABA

2019-10-03

169.48

3

BIDU

2019-10-01

102.00

4

BIDU

2019-10-02

102.62

5

BIDU

2019-10-03

104.32

6

IQ

2019-10-01

15.92

7

IQ

2019-10-02

15.72

8

IQ

2019-10-03

16.06

9

JD

2019-10-01

28.19

10

JD

2019-10-02

28.06

11

JD

2019-10-03

28.80

二、Series有多层索引MultiIndex怎样筛选数据?

ser
公司    日期        
BABA  2019-10-01    165.15
      2019-10-02    165.77
      2019-10-03    169.48
BIDU  2019-10-01    102.00
      2019-10-02    102.62
      2019-10-03    104.32
IQ    2019-10-01     15.92
      2019-10-02     15.72
      2019-10-03     16.06
JD    2019-10-01     28.19
      2019-10-02     28.06
      2019-10-03     28.80
Name: 收盘, dtype: float64
ser.loc['BIDU']
日期
2019-10-01    102.00
2019-10-02    102.62
2019-10-03    104.32
Name: 收盘, dtype: float64
# 多层索引,可以用元组的形式筛选
ser.loc[('BIDU', '2019-10-02')]
102.62
ser.loc[:, '2019-10-02']
公司
BABA    165.77
BIDU    102.62
IQ       15.72
JD       28.06
Name: 收盘, dtype: float64

三、DataFrame的多层索引MultiIndex

stocks.head()



日期

公司

收盘

开盘



交易量

涨跌幅

0

2019-10-03

BIDU

104.32

102.35

104.73

101.15

2.24

0.02

1

2019-10-02

BIDU

102.62

100.85

103.24

99.50

2.69

0.01

2

2019-10-01

BIDU

102.00

102.80

103.26

101.00

1.78

-0.01

3

2019-10-03

BABA

169.48

166.65

170.18

165.00

10.39

0.02

4

2019-10-02

BABA

165.77

162.82

166.88

161.90

11.60

0.00

stocks.set_index(['公司', '日期'], inplace=True)
stocks



收盘

开盘



交易量

涨跌幅

公司

日期

BIDU

2019-10-03

104.32

102.35

104.73

101.15

2.24

0.02

2019-10-02

102.62

100.85

103.24

99.50

2.69

0.01

2019-10-01

102.00

102.80

103.26

101.00

1.78

-0.01

BABA

2019-10-03

169.48

166.65

170.18

165.00

10.39

0.02

2019-10-02

165.77

162.82

166.88

161.90

11.60

0.00

2019-10-01

165.15

168.01

168.23

163.64

14.19

-0.01

IQ

2019-10-03

16.06

15.71

16.38

15.32

10.08

0.02

2019-10-02

15.72

15.85

15.87

15.12

8.10

-0.01

2019-10-01

15.92

16.14

16.22

15.50

11.65

-0.01

JD

2019-10-03

28.80

28.11

28.97

27.82

8.77

0.03

2019-10-02

28.06

28.00

28.22

27.53

9.53

0.00

2019-10-01

28.19

28.22

28.57

27.97

10.64

0.00

stocks.index
MultiIndex([('BIDU', '2019-10-03'),
            ('BIDU', '2019-10-02'),
            ('BIDU', '2019-10-01'),
            ('BABA', '2019-10-03'),
            ('BABA', '2019-10-02'),
            ('BABA', '2019-10-01'),
            (  'IQ', '2019-10-03'),
            (  'IQ', '2019-10-02'),
            (  'IQ', '2019-10-01'),
            (  'JD', '2019-10-03'),
            (  'JD', '2019-10-02'),
            (  'JD', '2019-10-01')],
           names=['公司', '日期'])
stocks.sort_index(inplace=True)
stocks



收盘

开盘



交易量

涨跌幅

公司

日期

BABA

2019-10-01

165.15

168.01

168.23

163.64

14.19

-0.01

2019-10-02

165.77

162.82

166.88

161.90

11.60

0.00

2019-10-03

169.48

166.65

170.18

165.00

10.39

0.02

BIDU

2019-10-01

102.00

102.80

103.26

101.00

1.78

-0.01

2019-10-02

102.62

100.85

103.24

99.50

2.69

0.01

2019-10-03

104.32

102.35

104.73

101.15

2.24

0.02

IQ

2019-10-01

15.92

16.14

16.22

15.50

11.65

-0.01

2019-10-02

15.72

15.85

15.87

15.12

8.10

-0.01

2019-10-03

16.06

15.71

16.38

15.32

10.08

0.02

JD

2019-10-01

28.19

28.22

28.57

27.97

10.64

0.00

2019-10-02

28.06

28.00

28.22

27.53

9.53

0.00

2019-10-03

28.80

28.11

28.97

27.82

8.77

0.03

四、DataFrame有多层索引MultiIndex怎样筛选数据?

重要知识】在选择数据时:

  • 元组(key1,key2)代表筛选多层索引,其中key1是索引第一级,key2是第二级,比如key1=JD, key2=2019-10-02
  • 列表[key1,key2]代表同一层的多个KEY,其中key1和key2是并列的同级索引,比如key1=JD, key2=BIDU
stocks.loc['BIDU']



收盘

开盘



交易量

涨跌幅

日期

2019-10-01

102.00

102.80

103.26

101.00

1.78

-0.01

2019-10-02

102.62

100.85

103.24

99.50

2.69

0.01

2019-10-03

104.32

102.35

104.73

101.15

2.24

0.02

stocks.loc[('BIDU', '2019-10-02'), :]
收盘     102.62
开盘     100.85
高      103.24
低       99.50
交易量      2.69
涨跌幅      0.01
Name: (BIDU, 2019-10-02), dtype: float64
stocks.loc[('BIDU', '2019-10-02'), '开盘']
100.85
stocks.loc[['BIDU', 'JD'], :]



收盘

开盘



交易量

涨跌幅

公司

日期

BIDU

2019-10-01

102.00

102.80

103.26

101.00

1.78

-0.01

2019-10-02

102.62

100.85

103.24

99.50

2.69

0.01

2019-10-03

104.32

102.35

104.73

101.15

2.24

0.02

JD

2019-10-01

28.19

28.22

28.57

27.97

10.64

0.00

2019-10-02

28.06

28.00

28.22

27.53

9.53

0.00

2019-10-03

28.80

28.11

28.97

27.82

8.77

0.03

stocks.loc[(['BIDU', 'JD'], '2019-10-03'), :]



收盘

开盘



交易量

涨跌幅

公司

日期

BIDU

2019-10-03

104.32

102.35

104.73

101.15

2.24

0.02

JD

2019-10-03

28.80

28.11

28.97

27.82

8.77

0.03

stocks.loc[(['BIDU', 'JD'], '2019-10-03'), '收盘']
公司    日期        
BIDU  2019-10-03    104.32
JD    2019-10-03     28.80
Name: 收盘, dtype: float64
stocks.loc[('BIDU', ['2019-10-02', '2019-10-03']), '收盘']
公司    日期        
BIDU  2019-10-02    102.62
      2019-10-03    104.32
Name: 收盘, dtype: float64
# slice(None)代表筛选这一索引的所有内容
stocks.loc[(slice(None), ['2019-10-02', '2019-10-03']), :]



收盘

开盘



交易量

涨跌幅

公司

日期

BABA

2019-10-02

165.77

162.82

166.88

161.90

11.60

0.00

2019-10-03

169.48

166.65

170.18

165.00

10.39

0.02

BIDU

2019-10-02

102.62

100.85

103.24

99.50

2.69

0.01

2019-10-03

104.32

102.35

104.73

101.15

2.24

0.02

IQ

2019-10-02

15.72

15.85

15.87

15.12

8.10

-0.01

2019-10-03

16.06

15.71

16.38

15.32

10.08

0.02

JD

2019-10-02

28.06

28.00

28.22

27.53

9.53

0.00

2019-10-03

28.80

28.11

28.97

27.82

8.77

0.03

stocks.reset_index()



公司

日期

收盘

开盘



交易量

涨跌幅

0

BABA

2019-10-01

165.15

168.01

168.23

163.64

14.19

-0.01

1

BABA

2019-10-02

165.77

162.82

166.88

161.90

11.60

0.00

2

BABA

2019-10-03

169.48

166.65

170.18

165.00

10.39

0.02

3

BIDU

2019-10-01

102.00

102.80

103.26

101.00

1.78

-0.01

4

BIDU

2019-10-02

102.62

100.85

103.24

99.50

2.69

0.01

5

BIDU

2019-10-03

104.32

102.35

104.73

101.15

2.24

0.02

6

IQ

2019-10-01

15.92

16.14

16.22

15.50

11.65

-0.01

7

IQ

2019-10-02

15.72

15.85

15.87

15.12

8.10

-0.01

8

IQ

2019-10-03

16.06

15.71

16.38

15.32

10.08

0.02

9

JD

2019-10-01

28.19

28.22

28.57

27.97

10.64

0.00

10

JD

2019-10-02

28.06

28.00

28.22

27.53

9.53

0.00

11

JD

2019-10-03

28.80

28.11

28.97

27.82

8.77

0.03