一、为什么要学习分层索引 Multindex?

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

二、基本用法

演示数据:百度、阿里巴巴、爱奇艺、京东四家公司的10天股票数据
数据来自:英为财经 本次演示提纲:

  1. Series的分层索引Multilndex
  2. Series有多层索引怎样筛选数据?
  3. DataFrame的多层索引Multilndex?
  4. DataFrame有多层素引怎样筛选数据?
fpath = '/Users/python/Desktop/means/ml-25m/互联网公司股票.xlsx'
df = pd.read_excel(fpath)

日期	公司	收盘	开盘	高	低	交易量	涨跌幅
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
df.shape     查看数据的总的行列
(12, 8)
df.head(3)   查看数据的前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
df['公司'].unique()   查看包含哪些公司
array(['BIDU', 'BABA', 'IQ', 'JD'], dtype=object)
df.index 查看索引的索引列
RangeIndex(start=0, stop=12, step=1)
以公司进行分组,查看公司收盘价的平均值
df.groupby('公司')['收盘'].mean()

公司
BABA    166.80
BIDU    102.98
IQ       15.90
JD       28.35
Name: 收盘, dtype: float64

三、Series 的分层索引Multilndex

以公司和日期进行分组,取收盘价的平均值
ser = df.groupby(['公司', '日期'])['收盘'].mean()


公司    日期        (公司是一个索引,日期也是一个索引)
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      查看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=['公司', '日期'])
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
两层索引都变成了普通的列,原来的Series 变成dataframe
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 有多层索引Multilndex如何筛选数据

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

df.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
DataFrame 如何设置分层索引
将公司名和日期设置为分层索引 
df.set_index(["公司", "日期"], inplace=True)

					收盘			开盘		高		低	交易量	涨跌幅
公司		日期						
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
df.index     # 查看df.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=['公司', '日期'])
df.sort_index(inplace=True) 对分组后结果重新排序,会按照字母、number类型自动排序;通过一级、二级进行排序

					收盘	     开盘	  高	  低	交易量	 涨跌幅
公司		日期						
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
筛选第一层索引
df.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
筛选多层索引 传入元组
df.loc[('BIDU', '2019-10-02'), :] 查询一级索引是BIDU,二级索引是2019-10-02 数据 (取所有列)

收盘     	102.62
开盘     	100.85
高      	103.24
低       	99.50
交易量       2.69
涨跌幅       0.01
Name: (BIDU, 2019-10-02), dtype: float64
多层索引下查询某个单元格
df.loc[('BIDU', '2019-10-02'), '收盘'] # 查询一级索引是BIDU,二级索引是2019-10-02 收盘的价格(取单个单元格)
102.62
并列筛选:如果是列表,同一级索引
df.loc[['BIDU', 'JD'], :] 查询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
混合筛选 
df.loc[(['BIDU', 'JD'], '2019-10-02'), :]   查询BIDU、JD在2019-10-02所有数据
					收盘		开盘			高    低 	交易量	涨跌幅
公司	日期						
BIDU	2019-10-02	102.62	100.85	103.24	99.50	2.69	0.01
JD		2019-10-02	28.06	28.00	28.22	27.53	9.53	0.00
df.loc[(['BIDU', 'JD'], '2019-10-02'), '收盘']  查询BIDU、JD在2019-10-02的收盘价是多少

公司    日期        
BIDU  2019-10-02    102.62
JD    2019-10-02     28.06 
Name: 收盘, dtype: float64
df.loc[('BIDU', ['2019-10-02', '2019-10-03']), '收盘'] 查询BIDU在2019-10-02、2019-10-03两天的收盘价

公司    日期        
BIDU  2019-10-02    102.62
      2019-10-03    104.32
Name: 收盘, dtype: float64
slice(None) 代表筛选这以索引的所有内容
df.loc[(slice(None), ['2019-10-02', '2019-10-03']), :]  查询所有公司在2019-10-02、2019-10-03两天的数据 (slice(None) 只能这样写)

					收盘		开盘		高		低		交易量	涨跌幅
公司		日期						
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
df.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