python学习——pandas层次化索引

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]:
  语文数学python
Michael期中 126 111 14
期末 101 37 145
Lisa期中 95 138 111
期末 117 60 5
Po期中 134 131 88
期末 56 85 113
 

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]:
  JavaHtml5Python
张三期中 120 119 137
期末 101 1 115
李四期中 66 117 121
期末 127 69 70
Michael期中 41 25 128
期末 101 7 10
 
  • 使用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]:
  SpringSummerAutumnWinter
张三期中 143 84 10 74
期末 66 72 71 115
李四期中 98 126 37 42
期末 90 10 5 90
Sara期中 104 95 93 28
期末 139 7 143 122
 
  • 使用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]:
   SpringSummerAutumnWinter
张三middleA 134 23 5 30
B 6 12 105 47
endA 149 121 50 56
B 17 28 90 89
SaramiddleA 110 64 86 20
B 20 28 76 136
endA 39 66 62 78
B 128 147 6 79
LisamiddleA 12 51 10 58
B 126 51 133 146
endA 25 57 107 30
B 19 31 55 120
 

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

练习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]:
 张三SaraLisa
 middleendmiddleendmiddleend
 ABABABABABAB
Spring 109 22 35 58 38 134 22 134 50 52 64 87
Summer 140 117 13 3 29 140 125 43 76 78 113 147
Autumn 128 31 146 76 60 40 34 51 111 129 64 142
Winter 111 91 54 12 89 45 127 28 42 58 7 6
 

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]:
  JavaHtml5Python
A期中 120 119 137
期末 101 1 115
B期中 66 117 121
期末 127 69 70
C期中 41 25 128
期末 101 7 10
In [46]:
df1['A':'B']
Out[46]:
  JavaHtml5Python
A期中 120 119 137
期末 101 1 115
B期中 66 117 121
期末 127 69 70
In [48]:
df1.iloc[0:4]
Out[48]:
  JavaHtml5Python
A期中 120 119 137
期末 101 1 115
B期中 66 117 121
期末 127 69 70
 

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

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

 

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

In [53]:
df2
Out[53]:
  SpringSummerAutumnWinter
张三期中 143 84 10 74
期末 66 72 71 115
李四期中 98 126 37 42
期末 90 10 5 90
Sara期中 104 95 93 28
期末 139 7 143 122
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]:
  SpringSummerAutumnWinter
张三期中 143 84 10 74
期末 66 72 71 115
李四期中 98 126 37 42
期末 90 10 5 90
 

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

练习9:

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

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

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

 

4. 索引的堆(stack)

 
  • stack()
  • unstack()
 

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

In [58]:
df4
Out[58]:
 张三SaraLisa
 middleendmiddleendmiddleend
 ABABABABABAB
Spring 109 22 35 58 38 134 22 134 50 52 64 87
Summer 140 117 13 3 29 140 125 43 76 78 113 147
Autumn 128 31 146 76 60 40 34 51 111 129 64 142
Winter 111 91 54 12 89 45 127 28 42 58 7 6
In [60]:
#stack = 堆--->行
#多层索引的列而言0,1,1:从上往下计数
df4.stack()
Out[60]:
  LisaSara张三
  endmiddleendmiddleendmiddle
SpringA 64 50 22 38 35 109
B 87 52 134 134 58 22
SummerA 113 76 125 29 13 140
B 147 78 43 140 3 117
AutumnA 64 111 34 60 146 128
B 142 129 51 40 76 31
WinterA 7 42 127 89 54 111
B 6 58 28 45 12 91
In [61]:
df4.stack(level=0)
Out[61]:
  endmiddle
  ABAB
SpringLisa 64 87 50 52
Sara 22 134 38 134
张三 35 58 109 22
SummerLisa 113 147 76 78
Sara 125 43 29 140
张三 13 3 140 117
AutumnLisa 64 142 111 129
Sara 34 51 60 40
张三 146 76 128 31
WinterLisa 7 6 42 58
Sara 127 28 89 45
张三 54 12 111 91
 

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

In [63]:
df2
Out[63]:
  SpringSummerAutumnWinter
张三期中 143 84 10 74
期末 66 72 71 115
李四期中 98 126 37 42
期末 90 10 5 90
Sara期中 104 95 93 28
期末 139 7 143 122
In [62]:
df2.unstack(level=1)
Out[62]:
 SpringSummerAutumnWinter
 期中期末期中期末期中期末期中期末
Sara 104 139 95 7 93 143 28 122
张三 143 66 84 72 10 71 74 115
李四 98 90 126 10 37 5 42 90
 

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

练习10:

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

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

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

 

5. 聚合操作

 

【注意】

  • 需要指定axis

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

 

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

In [64]:
df1
Out[64]:
  JavaHtml5Python
A期中 120 119 137
期末 101 1 115
B期中 66 117 121
期末 127 69 70
C期中 41 25 128
期末 101 7 10
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. 计算各科目张三李四的最高分

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

posted @ 2019-09-17 15:42  陪伴is最长情的告白  阅读(1259)  评论(0编辑  收藏  举报