【问题标题】:Pandas Melt with Multiple Value Vars具有多个值变量的 Pandas 融化
【发布时间】:2017-12-17 10:11:00
【问题描述】:

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

   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】:

    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
    

    【讨论】:

      【解决方案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】:

      你可以使用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
      

      【讨论】:

        猜你喜欢
        • 2015-02-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-02
        • 1970-01-01
        • 2017-11-22
        相关资源
        最近更新 更多