pandas 在Python中将多列标题df从宽格式转换为长格式

zdwk9cvp  于 2023-04-28  发布在  Python
关注(0)|答案(2)|浏览(123)

我想将Excel文件从宽格式转换为长格式。
我正在阅读一个excel文件,它不仅有两行标题,而且在标题中还包括合并的单元格。

| Task | Name | May,2022  | Jun,2022  | Jul,2022  |
|      |      |status|type|status|type|status|type|
| ---- | ---- |------|----|------|----|------|----|
| 1    | Tom  |1     |AB  |1     |DT  |0     |AB  | 
| 2    | John |0     |DT  |1     |CC  |0     |GH  |

预期输出:
| 任务|姓名|日期|地位|类型|
| --------------|--------------|--------------|--------------|--------------|
| 1|汤姆|2022年5月|1|AB|
| 1|汤姆|2022年6月|1|DT|
| 1|汤姆|2022年7月|0|AB|
| 二|约翰|2022年5月|0|DT|
| 二|约翰|2022年6月|1|CC|
| 二|约翰|2022年7月|0|生长激素|
我有什么:

import pandas as pd
df = pd.read_excel(path)
df = df.melt(id_vars=["Task","Name"],
     var_name="Date",
     value_name="Value")

我不知道如何处理多标题。我试着合并两个标题。

import pandas as pd
df = pd.read_excel(path, header[1,2])
df.columns = df.columns.to_series().ffill().values
df.columns.value[0]='Task'
df.columns.value[1]='Name'
df = df.melt(id_vars=["Task","Name"],
     var_name="Date",
     value_name="Value")

这将导致类似于:(我对日期转换很满意)
| 任务|姓名|(2022-05-01 00:00:00,状态)|(2022-05-01 00:00:00,类型)|
| --------------|--------------|--------------|--------------|
| 1|汤姆|1|AB|
| 二|约翰|0|DT|
melt函数返回一个KeyError 'Task'。即使这可以工作,我也需要以某种方式将日期从状态中分离出来,并输入到单独的列中。有人知道如何处理这样的数据吗?

pw9qyyiw

pw9qyyiw1#

您可以使用set_index来保留TaskName列,然后使用stackDate列,最后使用reset_index来获得预期的输出:

>>> (df.set_index(['Task', 'Name']).rename_axis(columns=['Date', None])
       .stack(level=0).reset_index())

   Task  Name      Date  status type
0     1   Tom  Jul,2022       0   AB
1     1   Tom  Jun,2022       1   DT
2     1   Tom  May,2022       1   AB
3     2  John  Jul,2022       0   GH
4     2  John  Jun,2022       1   CC
5     2  John  May,2022       0   DT

最小可重现示例:

data = {'index': [0, 1],
        'columns': [('Task', ''),
         ('Name', ''),
         ('May,2022', 'status'),
         ('May,2022', 'type'),
         ('Jun,2022', 'status'),
         ('Jun,2022', 'type'),
         ('Jul,2022', 'status'),
         ('Jul,2022', 'type')],
        'data': [[1, 'Tom', 1, 'AB', 1, 'DT', 0, 'AB'],
                 [2, 'John', 0, 'DT', 1, 'CC', 0, 'GH']],
        'index_names': [None],
        'column_names': [None, None]}
df = pd.DataFrame.from_dict(data, orient='tight')
rkkpypqq

rkkpypqq2#

首先在index和columns中为MulitIndex添加index_colheader

df = pd.read_excel(path, index_col=[0,1], header=[0,1])

print (df.index)
MultiIndex([(1,  'Tom'),
            (2, 'John')],
           names=['Task', 'Name'])

print (df.columns)
MultiIndex([('May,2022', 'status'),
            ('May,2022',   'type'),
            ('Jun,2022', 'status'),
            ('Jun,2022',   'type'),
            ('Jul,2022', 'status'),
            ('Jul,2022',   'type')],
           names=['Task', None])

因此,可以将DataFrame.stackDataFrame.rename_axisDataFrame.reset_index一起使用:

out = df.stack(0).rename_axis(('Task','Name','Date')).reset_index()
print (out)
   Task  Name      Date  status type
0     1   Tom  Jul,2022       0   AB
1     1   Tom  Jun,2022       1   DT
2     1   Tom  May,2022       1   AB
3     2  John  Jul,2022       0   GH
4     2  John  Jun,2022       1   CC
5     2  John  May,2022       0   DT

相关问题