代码之家  ›  专栏  ›  技术社区  ›  mike01010

pandas:具有多级列的数据帧向上移动日期索引以使其变平

  •  0
  • mike01010  · 技术社区  · 2 年前

    我收到的数据如下所示:

    import pandas as pd, numpy as np
    data = [['',           'CCC',     'CCC',     'AAA',   'BBB'  ],
            ['date',       'field1', 'file2',  'field1','field1'],
            ['01/01/2024',  100,      102,       103,     104   ],
            ['01/02/2024',  200,      202,       203,     204   ],
            ['01/03/2024',  300,      302,       303,     304   ]]
    
    df = pd.DataFrame(data)
    idx = pd.MultiIndex.from_arrays(df.iloc[:2,1:].values, names=['symbol', None])
    df = df.iloc[2:,1:].set_axis(df.iloc[2:,0].rename('date'))
    df = df.set_axis(idx, axis=1)
    df
    

    enter image description here

    我对数据帧进行了一些处理,然后我现在想把它压平一点,以确保“日期”在第二行(带有字段)。。因此,如果我要序列化到json或excel文件,它看起来就像上面的数组。 我在做这件事时遇到了问题。下面的代码有几个问题

    1. df.columns.levels[0] 似乎返回了一个类似集合的列表。。具有唯一值。因此,由于两个数组的宽度不同,在尝试执行多重索引时失败
    2. 它还返回一个排序列表,这意味着如果我将其作为索引添加回来,它将是无序的。
    l1_idx = list(df.columns.levels[0])
    df.columns = df.columns.droplevel(0)
    #reset to flatten out and shift up that 'date' column
    df = df.reset_index() 
    #now add back the level 0 index - how do we maintain the original order?
    idx = pd.MultiIndex.from_arrays([l1_idx, df.columns])
    df = data.set_axis(idx, axis=1)
    df
    

    我希望得到一个与上面的数组完全相似的数据帧,但没有“symbol”标签

    1 回复  |  直到 2 年前
        1
  •  1
  •   Cameron Riddell    2 年前

    IIUC,听起来你想取行索引的名称,并将其作为列索引的最后一级的名称插入。

    需要注意的是,这些类型的修改只能在的尾部完成 你的分析-特别是如果你打算不在 pandas 因为你需要撤销这里介绍的一些扭曲动作。

    import pandas as pd, numpy as np
    data = [['',           'CCC',     'CCC',     'AAA',   'BBB'  ],
            ['date',       'field1', 'file2',  'field1','field1'],
            ['01/01/2024',  100,      102,       103,     104   ],
            ['01/02/2024',  200,      202,       203,     204   ],
            ['01/03/2024',  300,      302,       303,     304   ]]
    
    df = pd.DataFrame(data)
    idx = pd.MultiIndex.from_arrays(df.iloc[:2,1:].values, names=['symbol', None])
    df = df.iloc[2:,1:].set_axis(df.iloc[2:,0].rename('date'))
    df = df.set_axis(idx, axis=1)
    print(df)
    # symbol        CCC          AAA    BBB
    #            field1 file2 field1 field1
    # date
    # 01/01/2024    100   102    103    104
    # 01/02/2024    200   202    203    204
    # 01/03/2024    300   302    303    304
    
    res1 = (
        df.rename_axis([df.columns.names[0], df.index.name], axis=1)
        .rename_axis(None, axis=0)
    )
    
    print(res1)
    # symbol        CCC          AAA    BBB
    # date       field1 file2 field1 field1
    # 01/01/2024    100   102    103    104
    # 01/02/2024    200   202    203    204
    # 01/03/2024    300   302    303    304
    
    ## alternatively…
    new_cols = pd.MultiIndex.from_tuples([(df.columns.names[0], df.index.name), *df.columns])
    res2 = df.reset_index().set_axis(new_cols, axis=1)
    print(res2)
    #        symbol    CCC          AAA    BBB
    #          date field1 file2 field1 field1
    # 0  01/01/2024    100   102    103    104
    # 1  01/02/2024    200   202    203    204
    # 2  01/03/2024    300   302    303    304