Search code examples
dataframeindexinggroup-bymulti-index

Get column names as index in multi index data frame


I have this data frame:

                 Abacate    Abóbora (inclui butternut)  Alface  Alho    
Region  years                                                                                   
PT      1986     NaN            NaN                      NaN    NaN 
        1987     NaN            NaN                      NaN    NaN 
        1988     NaN            NaN                      NaN    NaN 
        1989     NaN            NaN                      NaN    NaN 
        1990     NaN            NaN                      NaN    NaN 
...      ...     ...            ...                      ...    ... 
3       2017     NaN            NaN                      NaN    NaN 
        2018     NaN            NaN                      NaN    NaN 
        2019     50.0           NaN                      NaN    NaN 
        2020     50.0           NaN                      NaN    NaN 
        2021     50.0           NaN                      NaN    NaN 
324 rows × 95 columns

How can I do this data frame with 3 indexes ,i.e., how can I pass all the column names as the third index, like this:

                    
Region  years   Products                        Productivity                                                        
PT      1986    Abacate                           NaN
                Abóbora (inclui butternut)        NaN
                Alface                            NaN
                Alho                              NaN
        1987    Abacate                           NaN
                Abóbora (inclui butternut)        NaN
                Alface                            NaN
                Alho                              NaN                                
        1988    Abacate                           NaN
                Abóbora (inclui butternut)        NaN
                Alface                            NaN
                Alho                              NaN                                       
        1989    Abacate                           NaN
                Abóbora (inclui butternut)        NaN
                Alface                            NaN
                Alho                              NaN          
        1990    Abacate                           NaN
                Abóbora (inclui butternut)        NaN
                Alface                            NaN
                Alho                              NaN          
...      ...     ...            ...                      ...    ... 
3       2017    Abacate                           NaN
                Abóbora (inclui butternut)        NaN
                Alface                            NaN
                Alho                              NaN           
        2018    Abacate                           NaN
                Abóbora (inclui butternut)        NaN
                Alface                            NaN
                Alho                              NaN 
        2019    Abacate                           50.0
                Abóbora (inclui butternut)        NaN
                Alface                            NaN
                Alho                              NaN 
        2020    Abacate                           50.0
                Abóbora (inclui butternut)        NaN
                Alface                            NaN
                Alho                              NaN 
        2021    Abacate                           50.0
                Abóbora (inclui butternut)        NaN
                Alface                            NaN
                Alho                              NaN  

As I have much more columns than the ones I wrote here, I tried doing a "for" function that runs all columns and then grupby with the other indexes but it doesn't work.


Solution

  • You are looking for stack:

    df = df.stack().to_frame().rename(columns={0:"Productivity"})
    

    Full example:

    df = pd.DataFrame(data=[["PT","1986","NaN","NaN","NaN","NaN"],["PT","1987","NaN","NaN","NaN","NaN"],["PT","1988","NaN","NaN","NaN","NaN"],["PT","1989","NaN","NaN","NaN","NaN"],["PT","1990","NaN","NaN","NaN","NaN"],["3","2017","NaN","NaN","NaN","NaN"],["3","2018","NaN","NaN","NaN","NaN"],["3","2019","50.0","NaN","NaN","NaN"],["3","2020","50.0","NaN","NaN","NaN"],["3","2021","50.0","NaN","NaN","NaN"]], columns=["Region","years","Abacate","Abóbora (inclui butternut)","Alface","Alho"])
    
    df = df.groupby(["Region", "years"]).agg(Abacate=("Abacate","sum"), Abóbora=("Abóbora (inclui butternut)","sum"), Alface=("Alface","sum"), Alho=("Alho","sum"))
    
    df = df.rename_axis("Products", axis="columns")
    
    df = df.stack().to_frame().rename(columns={0:"Productivity"})
    

    Output:

                          Productivity
    Region years Products             
    3      2017  Abacate           NaN
                 Abóbora           NaN
                 Alface            NaN
                 Alho              NaN
           2018  Abacate           NaN
                 Abóbora           NaN
                 Alface            NaN
                 Alho              NaN
           2019  Abacate          50.0
                 Abóbora           NaN
                 Alface            NaN
                 Alho              NaN
           2020  Abacate          50.0
                 Abóbora           NaN
                 Alface            NaN
                 Alho              NaN
           2021  Abacate          50.0
                 Abóbora           NaN
                 Alface            NaN
                 Alho              NaN
    PT     1986  Abacate           NaN
                 Abóbora           NaN
                 Alface            NaN
                 Alho              NaN
           1987  Abacate           NaN
                 Abóbora           NaN
                 Alface            NaN
                 Alho              NaN
           1988  Abacate           NaN
                 Abóbora           NaN
                 Alface            NaN
                 Alho              NaN
           1989  Abacate           NaN
                 Abóbora           NaN
                 Alface            NaN
                 Alho              NaN
           1990  Abacate           NaN
                 Abóbora           NaN
                 Alface            NaN
                 Alho              NaN