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
    

二、索引的变形

  1. unstack

    将行索引转换为列索引,输入参数为移动的层号,默认为最内层,且可以转换多层。

    例如,先生成一个表:

     df = pd.DataFrame(np.ones((4,2)),
       ....:                   index = pd.Index([('A', 'cat', 'big'),
       ....:                                     ('A', 'dog', 'small'),
       ....:                                     ('B', 'cat', 'big'),
       ....:                                     ('B', 'dog', 'small')]),
       ....:                   columns=['col_1', 'col_2'])
       ....: 
    
     df
    Out[41]: 
                 col_1  col_2
    A cat big      1.0    1.0
      dog small    1.0    1.0
    B cat big      1.0    1.0
      dog small    1.0    1.0
    

    将内层(big和small)移动到列索引上:

    df.unstack()
    Out[42]: 
          col_1       col_2      
            big small   big small
    A cat   1.0   NaN   1.0   NaN
      dog   NaN   1.0   NaN   1.0
    B cat   1.0   NaN   1.0   NaN
      dog   NaN   1.0   NaN   1.0
    

    移动多个层:

    df.unstack([0,2])
    Out[44]: 
        col_1                  col_2                 
            A          B           A          B      
          big small  big small   big small  big small
    cat   1.0   NaN  1.0   NaN   1.0   NaN  1.0   NaN
    dog   NaN   1.0  NaN   1.0   NaN   1.0  NaN   1.0
    

    注意点:

    • 也具有唯一性,必须保证 被转为列索引的行索引层 和 被保留的行索引层 构成的组合是唯一的
  2. stack

    把列索引的层压入行索引中,用法和unstack类似。

三、其他变形函数

  1. explode

    对某一列的元素纵向展开,输入为要展开的列:

    df_ex = pd.DataFrame({'A': [[1, 2],
       ....:                          'my_str',
       ....:                          {1, 2},
       ....:                          pd.Series([3, 4])],
       ....:                       'B': 1})
       ....: 
    
    df_ex.explode('A')
    Out[61]: 
            A  B
    0       1  1
    0       2  1
    1  my_str  1
    2  {1, 2}  1
    3       3  1
    3       4  1
    
    
  2. get_dummies

    使用one-hot编码构建特征,例如:

    s = pd.Series(list('abca'))
    pd.get_dummies(s)
    Out:
       a  b  c
    0  1  0  0
    1  0  1  0
    2  0  0  1
    3  1  0  0
    

四、练习

  1. Ex1

    a.思路:使用pivot函数将长表变为宽表,需要变换的列为YYYY

    df_new = df.pivot(index=['COUNTY','State','SubstanceName'],
             columns='YYYY',
             values=['DrugReports'])
    

    看了答案后发现还要reset_index:

    df_new.reset_index.rename_axis(columns=:'YYYY':'')
    

    b.思路:使用melt函数,然后还需要将nan值舍弃:

    df_re = df_new.melt(id_vars=['COUNTY','State','SubstanceName'],
                     value_vars=[2010,2011,2012,2013,2014,2015,2016,2017],
                     var_name = 'YYYY',
                     value_name = 'DrugReports').dropna(subset=['DrugReports'])
    

    c. 使用pivot_table:

     res1 = df.pivot_table(index='YYYY', columns='State',
                       values='DrugReports', aggfunc='sum')
    

    使用 groupby+unstack:

    df_new = df.groupby(['State', 'YYYY'])['DrugReports'].sum()
    res2 = df_new.unstack(0)
    
  2. Ex2

    df = df.rename(columns={'Chinese':'new_Chinese', 'Math':'new_Math'})
    pd.wide_to_long(df,
                    stubnames=['new'],
                    i = ['Class', 'Name'],
                    j='Subject',
                    sep='_',
                    suffix='.+').reset_index().rename(columns={'new ':'Grade'})
    

posted @ 2020-12-27 20:48  爱睡觉的皮卡丘  阅读(69)  评论(0编辑  收藏  举报