【问题标题】:Create new columns based on existing columns and values in Pandas根据 Pandas 中的现有列和值创建新列
【发布时间】:2018-10-07 11:45:22
【问题描述】:

(1) 考虑如下DataFrame:

    d   e     val
-----------------
1   0   40    125
2  10   35    150
3  11   30    110
4  15   65    115

有没有办法到达下一行:

     val_0    val_10    val_11    val_15    e_0    e_10    e_11    e_15
-----------------------------------------------------------------------
1      125      150        110       115     40      35      30      65

这很容易通过手动迭代行来完成,但理想情况下我会寻找矢量化解决方案。基本上,我认为我所追求的是一种基于某些列名 + 列值创建/分配行的方法。

(2) 下一步是实际输出每个值一行,给定一组列。以上面的例子为基础,如下:

    d   e     val   gp
----------------------
1   0   40    125    3
2  10   35    150    3
3  11   30    110    3
4  15   65    115    3
1   0   70    225    4
2  10   85    250    4
3  11   90    210    4
4  15   95    215    4

会输出:

gp   val_0   val_10   val_11   val_15   e_0    e_10    e_11    e_15
-------------------------------------------------------------------
 3     125      150      110      115    40      35      30      65
 4     225      250      210      215    70      85      90      95

同样,在解决了 (1) 后执行 (2) 可以通过简单的 groupby('gp').apply(some_fun) 完成,但如果 Pandas 中存在内置方法来执行此操作,那么在性能方面将是一个巨大的好处。

【问题讨论】:

    标签: python pandas dataframe pivot-table pandas-groupby


    【解决方案1】:

    您可以使用一些数据框重塑和列标题展平:

    df_out = df.set_index('d').unstack().to_frame().T
    df_out.columns = df_out.columns.map('{0[0]}_{0[1]}'.format)
    

    输出:

       e_0  e_10  e_11  e_15  val_0  val_10  val_11  val_15
    0   40    35    30    65    125     150     110     115
    

    编辑以处理多行

    df_out = df.set_index(['gp','d']).unstack()
    df_out.columns = df_out.columns.map('{0[0]}_{0[1]}'.format)
    

    输出:

        e_0  e_10  e_11  e_15  val_0  val_10  val_11  val_15
    gp                                                      
    3    40    35    30    65    125     150     110     115
    4    70    85    90    95    225     250     210     215
    
    df_out = df_out.reset_index()
    
       gp  e_0  e_10  e_11  e_15  val_0  val_10  val_11  val_15
    0   3   40    35    30    65    125     150     110     115
    1   4   70    85    90    95    225     250     210     215
    

    【讨论】:

      【解决方案2】:

      这是原始问题的一种解决方案。

      val = pd.Series(df['val'].values, index='val_'+df['d'].apply(str))
      e = pd.Series(df['e'].values, index='e_'+df['e'].apply(str))
      
      res = pd.concat([val, e]).to_frame().T
      
      print(res)
      
         val_0  val_10  val_11  val_15  e_40  e_35  e_30  e_65
      0    125     150     110     115    40    35    30    65
      

      【讨论】:

      • 这绝对是有趣的。
      猜你喜欢
      • 1970-01-01
      • 2021-09-19
      • 2021-04-19
      • 1970-01-01
      • 2019-04-17
      • 1970-01-01
      • 2020-04-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多