引入模块
import pandas as pd
from pandas import Series,DataFrame
import matplotlib.pyplot as plt
创建示例DataFrame
# 用作案例 不要删 !!!
data=np.random.randint(0,150,size=(2,8))
index=["rose","jack"]
columns=pd.MultiIndex.from_product([["期中","期末"],["一模","二模"],["语文","英语"]])
df = DataFrame(data,index=index,columns=columns)
df
期中 | 期末 | |||||||
---|---|---|---|---|---|---|---|---|
一模 | 二模 | 一模 | 二模 | |||||
语文 | 英语 | 语文 | 英语 | 语文 | 英语 | 语文 | 英语 | |
rose | 87 | 113 | 91 | 135 | 126 | 136 | 57 | 41 |
jack | 7 | 125 | 135 | 119 | 44 | 145 | 127 | 63 |
1. 索引的堆(stack)
stack()
unstack()
stack() columns -> index 列标题变行标题(数据也会跟着标题走)
df.stack() # 把列的标题 放到行上
df
期中 | 期末 | ||||
---|---|---|---|---|---|
一模 | 二模 | 一模 | 二模 | ||
rose | 英语 | 113 | 135 | 136 | 41 |
语文 | 87 | 91 | 126 | 57 | |
jack | 英语 | 125 | 119 | 145 | 63 |
语文 | 7 | 135 | 44 | 127 |
df.stack().stack()
期中 | 期末 | |||
---|---|---|---|---|
rose | 英语 | 一模 | 113 | 136 |
二模 | 135 | 41 | ||
语文 | 一模 | 87 | 126 | |
二模 | 91 | 57 | ||
jack | 英语 | 一模 | 125 | 145 |
二模 | 119 | 63 | ||
语文 | 一模 | 7 | ||
二模 | 135 | 127 |
df.stack().stack().stack()
结果为:
rose 英语 一模 期中 113
期末 136
二模 期中 135
期末 41
语文 一模 期中 87
期末 126
二模 期中 91
期末 57
jack 英语 一模 期中 125
期末 145
二模 期中 119
期末 63
语文 一模 期中 7
期末 44
二模 期中 135
期末 127
dtype: int32
type(df.stack().stack().stack())
结果为:
pandas.core.series.Series
对于单级列索引,列索引没了,直接变Series
对于多级列索引,通过level指明要转换的columns
level 的值默认为-1(最内层);取值从外往里 从0递增
df.stack(level=0) # level 索引的级别 默认是-1 -1就是最里面的 level的值 从外到内 0 1 2 3
一模 | 二模 | ||||
---|---|---|---|---|---|
英语 | 语文 | 英语 | 语文 | ||
rose | 期中 | 113 | 87 | 135 | 91 |
期末 | 136 | 126 | 41 | 57 | |
jack | 期中 | 125 | 7 | 119 | 135 |
期末 | 145 | 44 | 63 | 127 |
df.stack(level=1)
期中 | 期末 | ||||
---|---|---|---|---|---|
英语 | 语文 | 英语 | 语文 | ||
rose | 一模 | 113 | 87 | 136 | 126 |
二模 | 135 | 91 | 41 | 57 | |
jack | 一模 | 125 | 7 | 145 | 44 |
二模 | 119 | 135 | 63 | 127 |
【小技巧】使用stack()时,level等于哪个columns,哪个columns就消失,变成index(行标题)
unstack() index -> columns 行标题变列标题(数据也会跟着标题走)
df.unstack()
结果为:
期中 一模 语文 rose 87
jack 7
英语 rose 113
jack 125
二模 语文 rose 91
jack 135
英语 rose 135
jack 119
期末 一模 语文 rose 126
jack 44
英语 rose 136
jack 145
二模 语文 rose 57
jack 127
英语 rose 41
jack 63
dtype: int32
df1 = df.stack().stack()
df1
期中 | 期末 | |||
---|---|---|---|---|
rose | 英语 | 一模 | 113 | 136 |
二模 | 135 | 41 | ||
语文 | 一模 | 87 | 126 | |
二模 | 91 | 57 | ||
jack | 英语 | 一模 | 125 | 145 |
二模 | 119 | 63 | ||
语文 | 一模 | 7 | 44 | |
二模 | 135 | 12 |
df1.unstack(level=2)
期中 | 期末 | ||||
---|---|---|---|---|---|
一模 | 二模 | 一模 | 二模 | ||
rose | 英语 | 113 | 135 | 136 | 41 |
语文 | 87 | 91 | 126 | 57 | |
jack | 英语 | 125 | 119 | 145 | 63 |
语文 | 7 | 135 | 44 | 127 |
df1.unstack(level=-1)
与level=2 结果保持一致
练习:行列互换
df.stack().stack().stack().unstack(level=0)
rose | jack | |||
---|---|---|---|---|
英语 | 一模 | 期中 | 113 | 125 |
1 | 期末 | 136 | 145 | |
二模 | 二模 | 期中 | 135 | 119 |
期末 | 41 | 63 | ||
语文 | 一模 | 期中 | 87 | 7 |
期末 | 126 | 44 | ||
二模 | 期中 | 91 | 135 | |
期末 | 57 | 127 |
【小技巧】使用unstack()时,level等于哪个index,哪个index就消失,变成columns(列标题)
============================================
练习:
- 将df变为两行,分别为期中期末
- 将df的行和列换位置(标题层级关系不能变)
============================================
df.stack(level=0).unstack(level=0)
一模 | 二模 | |||||||
---|---|---|---|---|---|---|---|---|
英语 | 语文 | 英语 | 语文 | |||||
rose | jack | rose | jack | rose | jack | rose | jack | |
期中 | 113 | 125 | 87 | 7 | 135 | 119 | 91 | 135 |
期末 | 136 | 145 | 126 | 44 | 41 | 63 | 57 | 127 |
df.stack(level=0).unstack(level=0).stack(level=0).stack(level=0)
jack | rose | |||
---|---|---|---|---|
期中 | 一模 | 英语 | 125 | 113 |
语文 | 7 | 87 | ||
二模 | 英语 | 119 | 135 | |
语文 | 135 | 91 | ||
期末 | 一模 | 英语 | 145 | 136 |
语文 | 44 | 126 | ||
二模 | 英语 | 63 | 41 | |
语文 | 127 | 57 |
2. 聚合操作
【注意】
- 需要指定axis
- 【小技巧】和unstack()相反,聚合的时候,axis等于哪一个,哪一个就保留。
所谓的聚合操作:最大值,最小值,平均数……
回忆一下ndarray的聚合
sum nansum、min、max、mean、argmin、argmax
data = np.random.randint(0,5,size=(5,5))
columns = list('ABCDE')
df = DataFrame(data=data,columns=columns)
df
A | B | C | D | E | |
---|---|---|---|---|---|
0 | 4 | 4 | 1 | 2 | 4 |
1 | 4 | 1 | 4 | 3 | 0 |
2 | 2 | 2 | 2 | 4 | 2 |
3 | 4 | 2 | 2 | 4 | 4 |
4 | 1 | 1 | 0 | 1 | 4 |
df.sum() # 默认是对 列进行聚合
结果为:
A 15
B 10
C 9
D 14
E 14
dtype: int64
如果想对 行进行聚合操作 可以调整 axis,axis 默认值是0 是对列做加和
df.sum(axis=1)
结果为:
0 15
1 12
2 12
3 16
4 7
dtype: int64
df.max()
结果为:
A 4
B 4
C 4
D 4
E 4
dtype: int32
df.min()
结果为:
A 1
B 1
C 0
D 1
E 0
dtype: int32
df.mean()
结果为:
A 3.0
B 2.0
C 1.8
D 2.8
E 2.8
dtype: float64
这些聚合操作都可以通过设置axis来切换方向
============================================
练习11:
- 计算期中期末各个科目平均成绩
- 计算各科目张三李四的最高分
============================================
index = ['张三','李四']
columns = pd.MultiIndex.from_product([['期中','期末'],['python','php','java']])
data = np.random.randint(0,150,size=(2,6))
score = DataFrame(data=data,index=index,columns=columns)
score
期中 | 期末 | |||||
---|---|---|---|---|---|---|
python | php | java | python | php | java | |
张三 | 13 | 147 | 147 | 129 | 83 | 144 |
李四 | 131 | 148 | 40 | 7 | 97 | 3 |
score.mean()
结果为:
期中 python 72.0
php 147.5
java 93.5
期末 python 68.0
php 90.0
java 73.5
dtype: float64
score.max()#求每门的平均值
结果为:
期中 python 131
php 148
java 147
期末 python 129
php 97
java 144
dtype: int32
score.max(axis=1)#求每个人的总科目平均值
结果为:
张三 147
李四 148
dtype: int32