1. 程式人生 > 實用技巧 >pandas組隊學習:task5

pandas組隊學習:task5

一、變形

  1. pivot

    將長表變換為寬表,輸入有三個引數:

    • index:變形後的行索引
    • columns:需要轉換到列索引的列
    • values:列和行索引對應的值

    例如,先生成一個表:

    df = pd.DataFrame({'Class':[1,1,2,2],
                        'Name':['San Zhang','San Zhang','Si Li','Si Li'],
                       'Subject':['Chinese','Math','Chinese','Math'],
                        'Grade':[80,75,90,85]})
    df
    Out[57]: 
       Class       Name  Subject  Grade
    0      1  San Zhang  Chinese     80
    1      1  San Zhang     Math     75
    2      2      Si Li  Chinese     90
    3      2      Si Li     Math     85
    

    然後將姓名作為變換後的行索,subject轉換為列索引:

    df.pivot(index='Name',columns='Subject',values='Grade')
    Out[58]: 
    Subject    Chinese  Math
    Name                    
    San Zhang       80    75
    Si Li           90    85
    

    注意點:

    • columns和index對應的組合需滿足唯一性,上面例子中,如果張三的數學改為語文,則會出錯,因為(張三,語文)這個組合出現了兩次。
    • 輸入的三個引數可以設為列表,返回多級索引。
  2. pivot_table

    為了解決povit中唯一性的限制,在povit的基礎上多增加了引數:

    • aggfunc:傳入聚合函式
    • margins:設為True可以統計邊際值

    回到第一節中的例子,張三和李四的考試有兩次:

    df = pd.DataFrame({'Name':['San Zhang', 'San Zhang','San Zhang', 'San Zhang',
                              'Si Li', 'Si Li', 'Si Li', 'Si Li'],
                      'Subject':['Chinese', 'Chinese', 'Math', 'Math',
                                    'Chinese', 'Chinese', 'Math', 'Math'],
                     'Grade':[80, 90, 100, 90, 70, 80, 85, 95]})
    df
    Out[61]: 
            Name  Subject  Grade
    0  San Zhang  Chinese     80
    1  San Zhang  Chinese     90
    2  San Zhang     Math    100
    3  San Zhang     Math     90
    4      Si Li  Chinese     70
    5      Si Li  Chinese     80
    6      Si Li     Math     85
    7      Si Li     Math     95
    

    使用pivot_table轉換為寬表,aggfunc輸入為兩次相同科目的平均值,同時統計邊界值:

    df.pivot_table(index ='Name',columns='Subject',values='Grade',aggfunc='mean',margins=True)
    Out[64]: 
    Subject    Chinese  Math    All
    Name                           
    San Zhang       85  95.0  90.00
    Si Li           75  90.0  82.50
    All             80  92.5  86.25
    
  3. melt

    將寬錶轉換為長表,為pivot的逆運算。輸入引數:

    • id_vars:不需要被轉換的列
    • value_vars:需要被轉換的列
    • var_name:被轉換列轉換後的名字
    • value_name:被轉換列下的資料轉換後的名字

    例如,先生成一個表:

    df = pd.DataFrame({'Class':[1,2],
                    'Name':['San Zhang', 'Si Li'],
                       'Chinese':[80, 90],
                         'Math':[80, 75]})
     df
    Out[66]: 
       Class       Name  Chinese  Math
    0      1  San Zhang       80    80
    1      2      Si Li       90    75
    

    然後使用melt函式將數學和語文合併成一個新的列:

    df.melt(id_vars = ['Class','Name'],
            value_vars=['Chinese','Math'],
            var_name='Subject',
            value_name = 'Grade')
    Out[68]: 
       Class       Name  Subject  Grade
    0      1  San Zhang  Chinese     80
    1      2      Si Li  Chinese     90
    2      1  San Zhang     Math     80
    3      2      Si Li     Math     75
    
  4. wide_to_long

    將寬表變為長表,只不過相比於melt函式,其對應的資訊可以表示多層含義:

    • stubnames:被轉換列下的資料轉換後的名字
    • i:不需要變換的列
    • j:被轉換列轉換後的名字

    例如,引入期中和期末資訊,將數學和語文的期中和期末進行展示,先生成表:

    df = pd.DataFrame({'Class':[1,2],'Name':['San Zhang', 'Si Li'],
       ....:                    'Chinese_Mid':[80, 75], 'Math_Mid':[90, 85],
       ....:                    'Chinese_Final':[80, 75], 'Math_Final':[90, 85]})
       ....: 
    df
    Out[29]: 
       Class       Name  Chinese_Mid  Math_Mid  Chinese_Final  Math_Final
    0      1  San Zhang           80        90             80          90
    1      2      Si Li           75        85             75          85
    

    進行轉換:

    pd.wide_to_long(df,
       ....:                 stubnames=['Chinese', 'Math'],
       ....:                 i = ['Class', 'Name'],
       ....:                 j='Examination',
       ....:                 sep='_',
       ....:                 suffix='.+')
       ....: 
    Out[30]: 
                                 Chinese  Math
    Class Name      Examination               
    1     San Zhang Mid               80    90
                    Final             80    90
    2     Si Li     Mid               75    85
                    Final             75    85