【问题标题】:pandas reshaping/transform the dataframe熊猫重塑/转换数据框
【发布时间】:2021-11-03 23:02:02
【问题描述】:

我有数据框 df:

col_name    col_month   col_value
abc         2021-01-31  233
abc         2021-02-28  784
abc         2021-03-31  7868
def         2021-02-28  3652
def         2021-03-31  344
def         2021-04-30  87

我需要结果为:

col_name    NAME        col1          col2            col3  
abc         col_month   2021-01-31    2021-02-28      2021-03-31
abc         col_value   233           784             7868
def         col_month   2021-02-28    2021-03-31      2021-04-30
def         col_value   3652          344             87

到目前为止我已经尝试过使用融化:

pd.melt(df, id_vars=['col_name'], var_name = 'NAME', value_name = 'VALUE')

这给出了结果:

col_name    NAME        VALUE
abc     col_month   2021-01-31
abc     col_month   2021-02-28
abc     col_month   2021-03-31
def     col_month   2021-02-28
def     col_month   2021-03-31
def     col_month   2021-04-30
abc     col_value   233
abc     col_value   784
abc     col_value   7868
def     col_value   3652
def     col_value   344
def     col_value   87

但我仍然无法得到想要的结果

【问题讨论】:

    标签: python pandas reshape pandas-melt


    【解决方案1】:

    这是另一种方式:

    df.assign(cols=df.groupby('col_name').cumcount()+1)\
      .set_index(['col_name','cols'])\
      .rename_axis('NAME', axis=1)\
      .stack().unstack(1)\
      .add_prefix('col')\
      .reset_index()
    

    输出:

    cols col_name       NAME        col1        col2        col3
    0         abc  col_month  2021-01-31  2021-02-28  2021-03-31
    1         abc  col_value         233         784        7868
    2         def  col_month  2021-02-28  2021-03-31  2021-04-30
    3         def  col_value        3652         344          87
    

    或者用,融化:

    df.assign(cols=df.groupby('col_name').cumcount()+1)\
      .melt(['col_name', 'cols'], var_name='NAME')\
      .set_index(['col_name', 'NAME', 'cols'])\
      .unstack()['value'].add_prefix('col')\
      .reset_index()
    

    【讨论】:

    • 一如既往的好作品~!您可以使用 .set_index(['col_name', df.groupby('col_name').cumcount() + 1]) 在第一个选项中避免显式分配
    • @HenryEcker 谢谢,伙计。我一如既往地感谢您提出的改进建议。
    【解决方案2】:

    尝试使用groupbyT

    >>> df.groupby('col_name').apply(lambda x: x.drop('col_name', axis=1).reset_index(drop=True).T.rename_axis(index='NAME')).rename(lambda x: f'col{x + 1}', axis=1).reset_index()
      col_name       NAME        col1        col2        col3
    0      abc  col_month  2021-01-31  2021-02-28  2021-03-31
    1      abc  col_value         233         784        7868
    2      def  col_month  2021-02-28  2021-03-31  2021-04-30
    3      def  col_value        3652         344          87
    >>> 
    

    或者试试meltpivot_table

    >>> x = df.melt('col_name')
    >>> d = {'': ['col_name', 'NAME']}
    >>> x.assign(idx=x.groupby(['col_name', 'variable']).cumcount()).pivot_table(index=['col_name', 'variable'], columns='idx', aggfunc=sum).reset_index().droplevel(0, axis=1).rename_axis(columns=None).rename(lambda x: f'col{x + 1}' if isinstance(x, int) else x, axis=1).rename(columns=lambda x: d.get(x, [x]).pop(0))
      col_name       NAME        col1        col2        col3
    0      abc  col_month  2021-01-31  2021-02-28  2021-03-31
    1      abc  col_value         233         784        7868
    2      def  col_month  2021-02-28  2021-03-31  2021-04-30
    3      def  col_value        3652         344          87
    >>> 
    

    【讨论】:

      【解决方案3】:

      使用meltgroupbyapply 的另一种方法:

      (
          df.melt('col_name',var_name='NAME')
          .groupby(['col_name','NAME'])
          .value.apply(list)
          .apply(pd.Series)
          .rename(columns = lambda x: f'col{x+1}')
          .reset_index()
      )
      

      如果数据集很大,请使用此版本,因为pd.Series 在大型数据集上可能会很慢。

      (
          df.melt('col_name',var_name='NAME')
          .groupby(['col_name','NAME'])
          .value.apply(list)
          .pipe(lambda x: pd.DataFrame(index=x.index, data=x.tolist()))
          .rename(columns = lambda x: f'col{x+1}')
          .reset_index()
      )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-08-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多