【问题标题】:Reshape wide to long in pandas在熊猫中重塑宽到长
【发布时间】:2021-02-09 00:20:05
【问题描述】:

假设我在 pandas 中有以下数据框:

             AA  BB  CC     
   date
   05/03     1   2   3  
   06/03     4   5   6  
   07/03     7   8   9  
   08/03     5   7   1  

我想将其转换为以下内容:

   AA 05/03    1
   AA 06/03    4
   AA 07/03    7
   AA 08/03    5
   BB 05/03    2
   BB 06/03    5
   BB 07/03    8
   BB 08/03    7
   CC 05/03    3
   CC 06/03    6
   CC 07/03    9
   CC 08/03    1

我该怎么做?

从宽到长转换的原因是,在下一阶段,我想根据日期和初始列名(AA、BB、CC)将此数据框与另一个数据框合并。

【问题讨论】:

    标签: python pandas dataframe reshape


    【解决方案1】:

    更新

    正如 George Liu 在another answer 中所展示的,pd.melt 是解决此问题的惯用、灵活和快速的解决方案。不要为此使用unstack


    unstack 返回一个带有多索引的系列:

        In [38]: df.unstack()
        Out[38]: 
            date 
        AA  05/03    1
            06/03    4
            07/03    7
            08/03    5
        BB  05/03    2
            06/03    5
            07/03    8
            08/03    7
        CC  05/03    3
            06/03    6
            07/03    9
            08/03    1
        dtype: int64
    

    您可以在返回的系列上调用 reset_index:

    In [39]: df.unstack().reset_index() 
    Out[39]:        
            
        level_0 date    0
    0   AA      05-03   1
    1   AA      06-03   4
    2   AA      07-03   7
    3   AA      08-03   5
    4   BB      05-03   2
    5   BB      06-03   5
    6   BB      07-03   8
    7   BB      08-03   7
    8   CC      05-03   3
    9   CC      06-03   6
    10  CC      07-03   9
    11  CC      08-03   1
    

    或者用多索引构造一个数据框:

    In [40]: pd.DataFrame(df.unstack())     
    Out[40]:        
            
                0
        date    
    AA  05-03   1
        06-03   4
        07-03   7
        08-03   5
    BB  05-03   2
        06-03   5
        07-03   8
        08-03   7
    CC  05-03   3
        06-03   6
        07-03   9
        08-03   1
    

    【讨论】:

    • 我们需要指的是运行百万数据的熔体还是堆栈?哪个更快
    • 对于我的虚拟测试 dfs(42 列,1k/100k/1M 行).melt.unstack.reset_index() 快 8 倍
    • @AndreS。确实如此。我已经更新了答案。
    【解决方案2】:

    使用pandas.melt从宽变长:

    df = pd.DataFrame({
        'date' : ['05/03', '06/03', '07/03', '08/03'],
        'AA' : [1, 4, 7, 5],
        'BB' : [2, 5, 8, 7],
        'CC' : [3, 6, 9, 1]
    }).set_index('date')
    df
    
            AA  BB  CC
    date            
    05/03   1   2   3
    06/03   4   5   6
    07/03   7   8   9
    08/03   5   7   1
    

    要转换,我们只需要重置索引然后融化:

    df = df.reset_index()
    pd.melt(df, id_vars='date', value_vars=['AA', 'BB', 'CC'])
    

    这是最终结果:

        date variable value
    0   05/03   AA  1
    1   06/03   AA  4
    2   07/03   AA  7
    3   08/03   AA  5
    4   05/03   BB  2
    5   06/03   BB  5
    6   07/03   BB  8
    7   08/03   BB  7
    8   05/03   CC  3
    9   06/03   CC  6
    10  07/03   CC  9
    11  08/03   CC  1
    

    【讨论】:

      【解决方案3】:

      对于我的虚拟测试 dfs(42 列,1k/100k/1M 行).melt.unstack.reset_index() 快 8 倍

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-12
        • 1970-01-01
        • 2017-07-07
        • 1970-01-01
        相关资源
        最近更新 更多