04 -pandas索引的堆(行列操作,交換行列)、聚合操作(求和、最大值、最小值、平均值等)
阿新 • • 發佈:2018-11-08
引入模組
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