Pandas 十七:分层索引MultiIndex
为什么要学习分层索引MultiIndex?
- 分层索引:在一个轴向上拥有多个索引层级,可以表达更高维度数据的形式;
- 可以更方便的进行数据筛选,如果有序则性能更好;
- groupby等操作的结果,如果是多KEY,结果是分层索引,需要会使用
- 一般不需要自己创建分层索引(MultiIndex有构造函数但一般不用)
演示数据:百度、阿里巴巴、爱奇艺、京东四家公司的10天股票数据
数据来自:英为财经
https://cn.investing.com/
本次演示提纲:
一、Series的分层索引MultiIndex
二、Series有多层索引怎样筛选数据?
三、DataFrame的多层索引MultiIndex
四、DataFrame有多层索引怎样筛选数据?
1
import pandas as pd
%matplotlib inline
1
stocks = pd.read_excel('./datas/stocks/互联网公司股票.xlsx')
3
stocks.shape
3
(12, 8)
4
stocks.head(3)
4
日期 公司 收盘 开盘 高 低 交易量 涨跌幅
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
5
stocks["公司"].unique()
5
array(['BIDU', 'BABA', 'IQ', 'JD'], dtype=object)
6
stocks.index
6
RangeIndex(start=0, stop=12, step=1)
7
stocks.groupby('公司')["收盘"].mean()
7
公司
BABA 166.80
BIDU 102.98
IQ 15.90
JD 28.35
Name: 收盘, dtype: float64
一、Series的分层索引MultiIndex
8
ser = stocks.groupby(['公司', '日期'])['收盘'].mean()
ser
8
公司 日期
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
多维索引中,空白的意思是:使用上面的值
9
ser.index
9
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=['公司', '日期'])
10
# unstack把二级索引变成列
ser.unstack()
10
日期 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
11
ser
11
公司 日期
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
12
ser.reset_index()
12
公司 日期 收盘
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怎样筛选数据?
13
ser
13
公司 日期
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
14
ser.loc['BIDU']
14
日期
2019-10-01 102.00
2019-10-02 102.62
2019-10-03 104.32
Name: 收盘, dtype: float64
15
# 多层索引,可以用元组的形式筛选
ser.loc[('BIDU', '2019-10-02')]
15
102.62
16
ser.loc[:, '2019-10-02']
16
公司
BABA 165.77
BIDU 102.62
IQ 15.72
JD 28.06
Name: 收盘, dtype: float64
三、DataFrame的多层索引MultiIndex
17
stocks.head()
17
日期 公司 收盘 开盘 高 低 交易量 涨跌幅
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
18
stocks.set_index(['公司', '日期'], inplace=True)
stocks
18
收盘 开盘 高 低 交易量 涨跌幅
公司 日期
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
19
stocks.index
19
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=['公司', '日期'])
20
stocks.sort_index(inplace=True)
stocks
20
收盘 开盘 高 低 交易量 涨跌幅
公司 日期
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
21
stocks.loc['BIDU']
21
收盘 开盘 高 低 交易量 涨跌幅
日期
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
22
stocks.loc[('BIDU', '2019-10-02'), :]
22
收盘 102.62
开盘 100.85
高 103.24
低 99.50
交易量 2.69
涨跌幅 0.01
Name: (BIDU, 2019-10-02), dtype: float64
23
stocks.loc[('BIDU', '2019-10-02'), '开盘']
23
100.85
24
stocks.loc[['BIDU', 'JD'], :]
24
收盘 开盘 高 低 交易量 涨跌幅
公司 日期
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
25
stocks.loc[(['BIDU', 'JD'], '2019-10-03'), :]
25
收盘 开盘 高 低 交易量 涨跌幅
公司 日期
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
26
stocks.loc[(['BIDU', 'JD'], '2019-10-03'), '收盘']
26
公司 日期
BIDU 2019-10-03 104.32
JD 2019-10-03 28.80
Name: 收盘, dtype: float64
27
stocks.loc[('BIDU', ['2019-10-02', '2019-10-03']), '收盘']
27
公司 日期
BIDU 2019-10-02 102.62
2019-10-03 104.32
Name: 收盘, dtype: float64
28
# slice(None)代表筛选这一索引的所有内容
stocks.loc[(slice(None), ['2019-10-02', '2019-10-03']), :]
28
收盘 开盘 高 低 交易量 涨跌幅
公司 日期
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
29
stocks.reset_index()
29
公司 日期 收盘 开盘 高 低 交易量 涨跌幅
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