zoukankan      html  css  js  c++  java
  • 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'})
      

  • 相关阅读:
    1月28日 layout_list_item
    1月27日 listview_MyListAdapter
    1月26日 listviewxml
    1月25日 textview
    1月24日 人月神话3
    体温填报(三)
    体温填报(二)
    体温填报(一)
    家庭记账本(六)
    家庭记账本(五)
  • 原文地址:https://www.cnblogs.com/zwrAI/p/14198602.html
Copyright © 2011-2022 走看看