pandas层次化索引

 

1. 创建多层行索引

 

1) 隐式构造

最常见的方法是给DataFrame构造函数的index参数传递两个或更多的数组

 
  • Series也可以创建多层索引
In [1]:
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
In [3]:
s = Series([1,2,3,4],
           index =[['a','a','b','b'],['期中','期末','期中','期末']] )
s
Out[3]:
a  期中    1
   期末    2
b  期中    3
   期末    4
dtype: int64
In [5]:
df = DataFrame(data = np.random.randint(0,150,size = (6,3)),
               columns = ['语文','数学','python'],
              index = [['Michael','Michael','Lisa','Lisa','Po','Po'],['期中','期末','期中','期末','期中','期末']])
#隐式创建
df
Out[5]:
Michael期中12611114
期末10137145
Lisa期中95138111
期末117605
Po期中13413188
期末5685113
 

2) 显示构造pd.MultiIndex

 
  • 使用数组
In [6]:
df1 = DataFrame(data = np.random.randint(0,150,size = (6,3)),
               columns = ["Java",'Html5','Python'],
               index = pd.MultiIndex.from_arrays([['张三','张三','李四','李四','Michael','Michael'],['期中','期末','期中','期末','期中','期末']]))

df1
Out[6]:
张三期中120119137
期末1011115
李四期中66117121
期末1276970
Michael期中4125128
期末101710
 
  • 使用tuple
In [7]:
df2 = DataFrame(data = np.random.randint(0,150,size = (6,4)),
               columns = ["Spring",'Summer','Autumn','Winter'],
               index = pd.MultiIndex.from_tuples([('张三','期中'),('张三','期末'),('李四','期中'),('李四','期末'),('Sara','期中'),('Sara','期末')]))

df2
Out[7]:
张三期中143841074
期末667271115
李四期中981263742
期末9010590
Sara期中104959328
期末1397143122
 
  • 使用product

    最简单,推荐使用

In [8]:
df3 = DataFrame(data = np.random.randint(0,150,size = (12,4)),
               columns = ["Spring",'Summer','Autumn','Winter'],
               index = pd.MultiIndex.from_product([['张三','Sara','Lisa'],['middle','end'],list('AB')]))

df3
Out[8]:
张三middleA13423530
B61210547
endA1491215056
B17289089
SaramiddleA110648620
B202876136
endA39666278
B128147679
LisamiddleA12511058
B12651133146
endA255710730
B193155120
 

============================================

练习8:

  1. 创建一个DataFrame,表示出张三李四期中期末各科成绩

============================================

 

2. 多层列索引

 

除了行索引index,列索引columns也能用同样的方法创建多层索引

In [16]:
df4 = DataFrame(data = np.random.randint(0,150,size = (4,12)),
               columns = pd.MultiIndex.from_product([['张三','Sara','Lisa'],['middle','end'],list('AB')]),
               index = ["Spring",'Summer','Autumn','Winter'])

df4
Out[16]:
Spring109223558381342213450526487
Summer14011713329140125437678113147
Autumn12831146766040345111112964142
Winter111915412894512728425876
 

3. 多层索引对象的索引与切片操作

 

1)Series的操作

 

【重要】对于Series来说,直接中括号[]与使用.loc[]完全一样,因此,推荐使用中括号索引和切片。

 

多层索引进行切片时,有些汉字,或者英文,不识别,运行异常,并不是代码的问题,自身的bug

 

(1) 索引

In [17]:
s
Out[17]:
a  期中    1
   期末    2
b  期中    3
   期末    4
dtype: int64
In [19]:
# 第一个参数,多层索引的第一维,第二个参数,多层索引第二维
s['a','期中']
Out[19]:
1
In [22]:
#['a','期中']作为一个参数
s[['a','期中']]
Out[22]:
a  期中    1
   期末    2
dtype: int64
In [24]:
s[['a','b','c']]
Out[24]:
a  期中    1
   期末    2
b  期中    3
   期末    4
dtype: int64
In [15]:
s.loc['李四','期末']
Out[15]:
109
 

(2) 切片

In [25]:
s['a':'b']
Out[25]:
a  期中    1
   期末    2
b  期中    3
   期末    4
dtype: int64
In [26]:
s.iloc[0:3]
Out[26]:
a  期中    1
   期末    2
b  期中    3
dtype: int64
In [31]:
s2 = Series(data = np.random.randint(0,150,size = 6),index = pd.MultiIndex.from_product([list('ABC'),['e','f']]))
s2
Out[31]:
A  e    136
   f    120
B  e     84
   f     56
C  e    142
   f    101
dtype: int32
In [32]:
s2['A':'C']
Out[32]:
A  e    136
   f    120
B  e     84
   f     56
C  e    142
   f    101
dtype: int32
In [33]:
s2.loc['A':'B']
Out[33]:
A  e    136
   f    120
B  e     84
   f     56
dtype: int32
 

2)DataFrame的操作

 

(1) 可以直接使用列名称来进行列索引

 

对于二维索引,如果包含中文,进行切片时,存在报错bug,不是代码问题

In [44]:
df1.index = pd.MultiIndex.from_product([list('ABC'),['期中','期末']])
df1
Out[44]:
A期中120119137
期末1011115
B期中66117121
期末1276970
C期中4125128
期末101710
In [46]:
df1['A':'B']
Out[46]:
A期中120119137
期末1011115
B期中66117121
期末1276970
In [48]:
df1.iloc[0:4]
Out[48]:
A期中120119137
期末1011115
B期中66117121
期末1276970
 

(2) 使用行索引需要用loc()等函数

【极其重要】推荐使用loc()函数

 

注意在对行索引的时候,若一级行索引还有多个,对二级行索引会遇到问题!也就是说,无法直接对二级索引进行索引,必须让二级索引变成一级索引后才能对其进行索引!

In [53]:
df2
Out[53]:
张三期中143841074
期末667271115
李四期中981263742
期末9010590
Sara期中104959328
期末1397143122
In [54]:
df2.loc['张三','期中']
Out[54]:
Spring    143
Summer     84
Autumn     10
Winter     74
Name: (张三, 期中), dtype: int32
In [55]:
df2.loc['张三'].loc['期中']
Out[55]:
Spring    143
Summer     84
Autumn     10
Winter     74
Name: 期中, dtype: int32
In [57]:
df2.loc[['张三','李四']]
Out[57]:
张三期中143841074
期末667271115
李四期中981263742
期末9010590
 

============================================

练习9:

  1. 分析比较Series和DataFrame各种索引的方式,熟练掌握.loc()方法

  2. 假设张三再一次在期中考试的时候因为特殊原因放弃英语考试,如何实现?

============================================

 

4. 索引的堆(stack)

 
  • stack()
  • unstack()
 

【小技巧】使用stack()的时候,level等于哪一个,哪一个就消失,出现在行里。

In [58]:
df4
Out[58]:
Spring109223558381342213450526487
Summer14011713329140125437678113147
Autumn12831146766040345111112964142
Winter111915412894512728425876
In [60]:
#stack = 堆--->行
#多层索引的列而言0,1,1:从上往下计数
df4.stack()
Out[60]:
SpringA6450223835109
B87521341345822
SummerA113761252913140
B14778431403117
AutumnA641113460146128
B14212951407631
WinterA7421278954111
B65828451291
In [61]:
df4.stack(level=0)
Out[61]:
SpringLisa64875052
Sara2213438134
张三355810922
SummerLisa1131477678
Sara1254329140
张三133140117
AutumnLisa64142111129
Sara34516040
张三1467612831
WinterLisa764258
Sara127288945
张三541211191
 

【小技巧】使用unstack()的时候,level等于哪一个,哪一个就消失,出现在列里。

In [63]:
df2
Out[63]:
张三期中143841074
期末667271115
李四期中981263742
期末9010590
Sara期中104959328
期末1397143122
In [62]:
df2.unstack(level=1)
Out[62]:
Sara1041399579314328122
张三143668472107174115
李四9890126103754290
 

============================================

练习10:

  1. 使用unstack()将ddd变为两行,分别为期中期末

  2. 使用unstack()将ddd变为四行,分别为四个科目

============================================

 

5. 聚合操作

 

【注意】

  • 需要指定axis

  • 【小技巧】和unstack()相反,聚合的时候,axis等于哪一个,哪一个就会进行计算。

 

所谓的聚合操作:平均数,方差,最大值,最小值……

In [64]:
df1
Out[64]:
A期中120119137
期末1011115
B期中66117121
期末1276970
C期中4125128
期末101710
In [65]:
#axis=0  进行行间计算
#axis=1 进行列间计算
df1.sum()
Out[65]:
Java      556
Html5     338
Python    581
dtype: int64
In [68]:
df1.sum(axis =1)
Out[68]:
A  期中    376
   期末    217
B  期中    304
   期末    266
C  期中    194
   期末    118
dtype: int64
In [69]:
df1.mean(axis = 1)
Out[69]:
A  期中    125.333333
   期末     72.333333
B  期中    101.333333
   期末     88.666667
C  期中     64.666667
   期末     39.333333
dtype: float64
In [72]:
#数据离散的程度,方差越大数值间差距大
df1.std(axis=1)
Out[72]:
A  期中    10.115994
   期末    62.171805
B  期中    30.664855
   期末    33.201406
C  期中    55.428633
   期末    53.425961
dtype: float64
 

============================================

练习11:

  1. 计算各个科目期中期末平均成绩

  2. 计算各科目张三李四的最高分

============================================

02-10 21:54