【问题标题】:Convert (flatten) multiple header Pandas dataframe转换(展平)多个标头 Pandas 数据帧
【发布时间】:2021-08-28 12:30:28
【问题描述】:

我有以下来自 Excel 文件 (link to the Excel file) 的 Pandas 数据框

我想通过将当前标题(前两行)转换为数据框列来使用 Pandas 展平 Excel 表。这是我想去的地方:

segment unit    category    sub_category    value
seg1    kg      cat01       sub_cat_1.1     1
seg2    kg      cat01       sub_cat_1.1     2
seg1    kg      cat01       sub_cat_1.2     3
seg2    kg      cat01       sub_cat_1.2     
seg1    kg      cat02       sub_cat_2.1     4
seg2    kg      cat02       sub_cat_2.1     5

到目前为止我所做的是以下内容,但它没有按预期工作:

import pandas as pd

_file_name = "stackoverflow_excel_data_example.xlsx"
df = pd.read_excel(_file_name,  header=[0,1]).sort_index()
df = df.stack()
print(df)

有谁知道如何将自定义类型的数据透视表转换为平面数据框?

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:
    df = pd.read_excel(..., header=[0, 1])
    df = (
        df
        .iloc[:, 2:]
        .set_index(df.iloc[:, 0])
        .set_index(df.iloc[:, 1], append=True)
        .stack([0, 1])
        .rename_axis(["segement", "quantity", "category", "sub_category"])
        .rename("value")
        .reset_index()
    )
    

    提供的示例输入的结果是

    【讨论】:

    • 很好的答案。 +1。添加.rename('value').reset_index()(并交换categorysub_category
    • 感谢您的回答。正如@Corralien 提到的,我必须添加.rename('value').reset_index()
    【解决方案2】:

    这里没有真正的魔法,你需要在之前重新组织你的MultiIndex

    df.columns = pd.MultiIndex.from_tuples([('segment', ''), ('unit', '')] +
                                           df.columns[2:].to_list(),
                                           names=df.columns[1])
    

    此时,df 看起来像:

    >>> df
    category     segment unit       cat01                   cat02
    sub_category              sub_cat_1.1 sub_cat_1.2 sub_cat_2.1 sub_cat_2.1.1 sub_cat_2.1.2 sub_cat_2.1.3 sub_cat_2.1.4
    0               seg1   kg           1         3.0           4           NaN           NaN           NaN           NaN
    1               seg2   kg           2         NaN           5           NaN           NaN           NaN           NaN
    

    现在您可以应用转换:

    >>> df.set_index(["segment", "unit"]) \
          .stack(level=[0, 1])\
          .rename("value") \
          .reset_index()
    
      segment unit category sub_category  value
    0    seg1   kg    cat01  sub_cat_1.1    1.0
    1    seg1   kg    cat01  sub_cat_1.2    3.0
    2    seg1   kg    cat02  sub_cat_2.1    4.0
    3    seg2   kg    cat01  sub_cat_1.1    2.0
    4    seg2   kg    cat02  sub_cat_2.1    5.0
    

    【讨论】:

    • 正是我需要的。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-03
    • 2021-03-25
    • 2017-02-04
    • 1970-01-01
    • 2021-04-26
    • 1970-01-01
    • 2021-11-16
    相关资源
    最近更新 更多