分层索引
MultiIndex就是一个分层索引对象
tup = [('beijing',2000),('beijing',2019),
('shanghai',2000),('shanghai',2019),
('guangzhou',2000),('guangzhou',2019)]
values = [10000,100000,6000,60000,4000,40000]
index = pd.MultiIndex.from_tuples(tup) # 利用元组生成MultiIndex
sss = pd.Series(values, index=index) # 提供一个MultiIndex作为索引
>>>
>beijing 2000 10000
2019 100000
shanghai 2000 6000
2019 60000
guangzhou 2000 4000
2019 40000
更多的创建MultiIndex的方法还有:
从列表:pd.MultiIndex.from_arrays([['a','a','b','b'],[1,2,1,2]])
从元组:pd.MultiIndex.from_tuples([('a',1),('a',2),('b',1),('b',2)])
笛卡儿积:pd.MultiIndex.from_product([['a','b'],[1,2]])
直接构造:pd.MultiIndex(levels=[['a','b'],[1,2]],labels=[[0,0,1,1],[0,1,0,1]])
#=========================
分层索引在重塑数据和数组透视表中非常重要。比如,我们可以使用unstack方法将数据在DataFrame中重新排列,也就是展开:
s.unstack()
1 2 3
a 0.283490 0.295529 0.277676
b 0.487573 NaN 0.091161
c 0.285157 -0.806851 NaN
d NaN -0.287969 -0.696511
#--------------------------------------------------------------------------------------
s.unstack().stack() # 反操作stack
a 1 0.283490
2 0.295529
3 0.277676
b 1 0.487573
3 0.091161
c 1 0.285157
2 -0.806851
d 2 -0.287969
3 -0.696511
#==================
对于DataFrame对象,每个轴都可以有分层索引,给index或columns提供一个多维数组,就可以分层:
高级分层索引
DataFrame对象
sort_index(level=1)
意思是在第2个层级上进行索引的排序。
swaplevel(0, 1)
的意思是将第0层和第1层的行索引进行交换。
原始:
state Ohio Colorado
color Green Red Green
key1 key2
a 1 0 1 2
b 1 6 7 8
a 2 3 4 5
b 2 9 10 11
#--------------------------------------
df.swaplevel(0, 1).sort_index(level=0)
state Ohio Colorado
color Green Red Green
key2 key1
1 a 0 1 2
b 6 7 8
2 a 3 4 5
b 9 10 11
使用DataFrame的列进行索引
df= pd.DataFrame({'a': range(7), 'b': range(7, 0, -1),
'c': ['one', 'one', 'one', 'two', 'two', 'two', 'two'],
'd': [0, 1, 2, 0, 1, 2, 3]})
df>>>
a b c d
0 0 7 one 0
1 1 6 one 1
2 2 5 one 2
3 3 4 two 0
4 4 3 two 1
5 5 2 two 2
6 6 1 two 3
set_index(['c','d'])
将c列和d列变成了分层的行索引
drop=False
则保留了原来的列数据
reset_index
是set_index
的反向操作
df2 = df.set_index(['c','d'])
df2
a b
c d
one 0 0 7
1 1 6
2 2 5
two 0 3 4
1 4 3
2 5 2
3 6 1
#--------------------------------------
df.set_index(['c','d'],drop=False)
a b c d
c d
one 0 0 7 one 0
1 1 6 one 1
2 2 5 one 2
two 0 3 4 two 0
1 4 3 two 1
2 5 2 two 2
3 6 1 two 3
#------------------------------------
df2.reset_index()
c d a b
0 one 0 0 7
1 one 1 1 6
2 one 2 2 5
3 two 0 3 4
4 two 1 4 3
5 two 2 5 2
6 two 3 6 1
DataFrame索引切片
如果MultiIndex不是有序的索引,那么大多数切片操作都会失败!这时候可以使用前面介绍过的sort_index方法先排下序。
In [19]: df = pd.DataFrame(np.arange(12).reshape((4, 3)),
...: index=[['a', 'a', 'b', 'b'], [1, 2, 1, 2]],
...: columns=[['Ohio', 'Ohio', 'Colorado'],
...: ['Green', 'Red', 'Green']])
...:
In [20]: df
Out[20]:
Ohio Colorado
Green Red Green
a 1 0 1 2
2 3 4 5
b 1 6 7 8
2 9 10 11
In [23]: df['Ohio','Colorado'] # 不能这么做,因为列索引分层了
KeyError Traceback (most recent call last)
---------------------------------------------------------------------------
In [24]: df[['Ohio','Colorado']] # 这样可以
Out[24]:
Ohio Colorado
Green Red Green
a 1 0 1 2
2 3 4 5
b 1 6 7 8
2 9 10 11
#----------------------------------------
In [25]: df['Ohio','Green'] # 每层提供一个参数
Out[25]:
a 1 0
2 3
b 1 6
2 9
Name: (Ohio, Green), dtype: int32
#----------------------------------------
In [26]: df.iloc[:2,:2] # 用隐式索引
Out[26]:
Ohio
Green Red
a 1 0 1
2 3 4
#----------------------------------------
In [28]: df.loc[:,('Ohio','Red')] # 这个比较难理解
Out[28]:
a 1 1
2 4
b 1 7
2 10
Name: (Ohio, Red), dtype: int32