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

问题描述 投票:0回答:1

我收到的数据如下所示:

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]
    似乎返回一个类似列表的集合..具有唯一值。因此,由于两个数组的宽度不同,尝试执行 MultiIndex 时会失败
  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

我希望得到一个与上面的数组完全相同的数据框。

python pandas
1个回答
0
投票

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
© www.soinside.com 2019 - 2024. All rights reserved.