1. 程式人生 > >04 -pandas索引的堆(行列操作,交換行列)、聚合操作(求和、最大值、最小值、平均值等)

04 -pandas索引的堆(行列操作,交換行列)、聚合操作(求和、最大值、最小值、平均值等)

引入模組

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(列標題)

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

練習:

  1. 將df變為兩行,分別為期中期末
  2. 將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:

  1. 計算期中期末各個科目平均成績
  2. 計算各科目張三李四的最高分

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

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