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' )
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-1-574feeeb8bb0> in <module>
----> 1 stocks = pd.read_excel('./datas/stocks/互联网公司股票.xlsx')
NameError: name 'pd' is not defined
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