【问题标题】:Pandas Melt with Multiple Value VarsPandas 与多个值变量融为一体
【发布时间】:2017-07-13 05:59:49
【问题描述】:

我有一个像这样的宽格式数据集

   Index Country     Variable 2000 2001 2002 2003 2004 2005
   0     Argentina   var1     12   15   18    17  23   29
   1     Argentina   var2     1    3    2     5   7    5
   2     Brazil      var1     20   23   25   29   31   32
   3     Brazil      var2     0    1    2    2    3    3

我想将我的数据重新整形为 long 以便年份、var1 和 var2 成为新列

  Index Country     year   var1 var2
  0     Argentina   2000   12   1
  1     Argentina   2001   15   3
  2     Argentina   2002   18   2
  ....
  6     Brazil      2000   20   0
  7     Brazil      2001   23   1

当我只有一个变量时,我可以通过编写代码来工作

df=(pd.melt(df,id_vars='Country',value_name='Var1', var_name='year'))

我不知道如何为 var1、var2、var3 等执行此操作。

【问题讨论】:

    标签: python pandas melt


    【解决方案1】:

    你可以使用stack和unstack的组合来代替melt:

    (df.set_index(['Country', 'Variable'])
       .rename_axis(['Year'], axis=1)
       .stack()
       .unstack('Variable')
       .reset_index())
    
    Variable    Country  Year  var1  var2
    0         Argentina  2000    12     1
    1         Argentina  2001    15     3
    2         Argentina  2002    18     2
    3         Argentina  2003    17     5
    4         Argentina  2004    23     7
    5         Argentina  2005    29     5
    6            Brazil  2000    20     0
    7            Brazil  2001    23     1
    8            Brazil  2002    25     2
    9            Brazil  2003    29     2
    10           Brazil  2004    31     3
    11           Brazil  2005    32     3
    

    【讨论】:

      【解决方案2】:

      选项 1

      使用 melt 然后 unstack 用于 var1、var2 等...

      (df1.melt(id_vars=['Country','Variable'],var_name='Year')
          .set_index(['Country','Year','Variable'])
          .squeeze()
          .unstack()
          .reset_index())
      

      输出:

      Variable    Country  Year  var1  var2
      0         Argentina  2000    12     1
      1         Argentina  2001    15     3
      2         Argentina  2002    18     2
      3         Argentina  2003    17     5
      4         Argentina  2004    23     7
      5         Argentina  2005    29     5
      6            Brazil  2000    20     0
      7            Brazil  2001    23     1
      8            Brazil  2002    25     2
      9            Brazil  2003    29     2
      10           Brazil  2004    31     3
      11           Brazil  2005    32     3
      

      选项 2

      使用pivot 然后stack

      (df1.pivot(index='Country',columns='Variable')
         .stack(0)
         .rename_axis(['Country','Year'])
         .reset_index())
      

      输出:

      Variable    Country  Year  var1  var2
      0         Argentina  2000    12     1
      1         Argentina  2001    15     3
      2         Argentina  2002    18     2
      3         Argentina  2003    17     5
      4         Argentina  2004    23     7
      5         Argentina  2005    29     5
      6            Brazil  2000    20     0
      7            Brazil  2001    23     1
      8            Brazil  2002    25     2
      9            Brazil  2003    29     2
      10           Brazil  2004    31     3
      11           Brazil  2005    32     3
      

      选项 3(ayhan 的解决方案)

      使用set_indexstackunstack

      (df.set_index(['Country', 'Variable'])
         .rename_axis(['Year'], axis=1)
         .stack()
         .unstack('Variable')
         .reset_index())
      

      输出:

      Variable    Country  Year  var1  var2
      0         Argentina  2000    12     1
      1         Argentina  2001    15     3
      2         Argentina  2002    18     2
      3         Argentina  2003    17     5
      4         Argentina  2004    23     7
      5         Argentina  2005    29     5
      6            Brazil  2000    20     0
      7            Brazil  2001    23     1
      8            Brazil  2002    25     2
      9            Brazil  2003    29     2
      10           Brazil  2004    31     3
      11           Brazil  2005    32     3
      

      【讨论】:

      • 我喜欢你以非常易于阅读的方式布置选项的方式:-)
      • @piRSquared 谢谢。
      【解决方案3】:

      numpy

      years = df.drop(['Country', 'Variable'], 1)
      y = years.values
      m = y.shape[1]
      c = df.Country.values
      v = df.Variable.values
      
      f0, u0 = pd.factorize(df.Country.values)
      f1, u1 = pd.factorize(df.Variable.values)
      
      w = np.empty((u1.size, u0.size, m), dtype=y.dtype)
      w[f1, f0] = y
      
      results = pd.DataFrame(dict(
              Country=u0.repeat(m),
              Year=np.tile(years.columns.values, u0.size),
          )).join(pd.DataFrame(w.reshape(-1, m * u1.size).T, columns=u1))
      
      results
      
            Country  Year  var1  var2
      0   Argentina  2000    12     1
      1   Argentina  2001    15     3
      2   Argentina  2002    18     2
      3   Argentina  2003    17     5
      4   Argentina  2004    23     7
      5   Argentina  2005    29     5
      6      Brazil  2000    20     0
      7      Brazil  2001    23     1
      8      Brazil  2002    25     2
      9      Brazil  2003    29     2
      10     Brazil  2004    31     3
      11     Brazil  2005    32     3
      

      【讨论】:

        猜你喜欢
        • 2017-12-17
        • 2013-03-16
        • 2020-12-02
        • 2018-03-22
        • 1970-01-01
        • 2015-02-21
        • 2018-08-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多