17 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)
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }
日期 | 公司 | 收盘 | 开盘 | 高 | 低 | 交易量 | 涨跌幅 | |
---|---|---|---|---|---|---|---|---|
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()
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }
日期 | 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()
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }
公司 | 日期 | 收盘 | |
---|---|---|---|
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()
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }
日期 | 公司 | 收盘 | 开盘 | 高 | 低 | 交易量 | 涨跌幅 | |
---|---|---|---|---|---|---|---|---|
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
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }
收盘 | 开盘 | 高 | 低 | 交易量 | 涨跌幅 | ||
---|---|---|---|---|---|---|---|
公司 | 日期 | ||||||
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
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }
收盘 | 开盘 | 高 | 低 | 交易量 | 涨跌幅 | ||
---|---|---|---|---|---|---|---|
公司 | 日期 | ||||||
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']
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }
收盘 | 开盘 | 高 | 低 | 交易量 | 涨跌幅 | |
---|---|---|---|---|---|---|
日期 | ||||||
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'], :]
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }
收盘 | 开盘 | 高 | 低 | 交易量 | 涨跌幅 | ||
---|---|---|---|---|---|---|---|
公司 | 日期 | ||||||
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'), :]
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }
收盘 | 开盘 | 高 | 低 | 交易量 | 涨跌幅 | ||
---|---|---|---|---|---|---|---|
公司 | 日期 | ||||||
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']), :]
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }
收盘 | 开盘 | 高 | 低 | 交易量 | 涨跌幅 | ||
---|---|---|---|---|---|---|---|
公司 | 日期 | ||||||
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()
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }
公司 | 日期 | 收盘 | 开盘 | 高 | 低 | 交易量 | 涨跌幅 | |
---|---|---|---|---|---|---|---|---|
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 |
本文使用 文章同步助手 同步