Python Pandas:如何将我的表从长格式转换为宽格式(下面的具体示例)?

Python Pandas:如何将我的表从长格式转换为宽格式(下面的具体示例)?,python,pandas,dataframe,Python,Pandas,Dataframe,差不多就是标题。我附上电子表格。我需要将“输入”表转换为“输出”表。我知道熊猫的事。但我无法使用它来提供所需的输出,输出中的行被扰乱了 import pandas as pd df=pd.read_excel('../../Downloads/test.xlsx',sheet_name='Input', header=0) newdf=pd.wide_to_long(df, [str(i) for i in range(2022,2028)], 'Hotel Name', 'value', se

差不多就是标题。我附上电子表格。我需要将“输入”表转换为“输出”表。我知道熊猫的事。但我无法使用它来提供所需的输出,输出中的行被扰乱了

import pandas as pd
df=pd.read_excel('../../Downloads/test.xlsx',sheet_name='Input', header=0)
newdf=pd.wide_to_long(df, [str(i) for i in range(2022,2028)], 'Hotel Name', 'value', sep='', suffix='.+')\
  .reset_index()\
  .sort_values('Hotel Name')\
  .drop('value', axis=1)
newdf
输出是


您可以创建
索引
/
多索引
,通过列名称中的所有列创建,然后通过
列中的多索引
创建,因此可以通过最后设置的索引名重塑,并通过将
索引中的多索引
转换为列,然后按列中值的顺序将
Val
列转换为有序的
category
,这样您就可以按正确的顺序添加:

df = pd.read_excel('test.xlsx')

df = df.set_index(['Hotel Name'])
df.columns = df.columns.str.split(n=1, expand=True)

cats = df.columns.get_level_values(1).unique()
print (cats)
Index(['Revenue', 'Cost', 'Profit', 'Cum. Profit'], dtype='object')

df = (df.stack()
        .rename_axis(('Hotel Name','Val'))
        .reset_index()
        .assign(Val = lambda x: pd.Categorical(x.Val, ordered=True, categories=cats))
        .sort_values(['Hotel Name','Val'])
        )
print (df.head())
   Hotel Name          Val  2022     2023      2024    2025    2026    2027  \
3     Hotel A      Revenue     0  35478.0   59130.0   94608  118260  141912   
0     Hotel A         Cost     0      0.0       0.0       0       0       0   
2     Hotel A       Profit     0  35478.0   59130.0   94608  118260  141912   
1     Hotel A  Cum. Profit     0  35478.0   94608.0  189216  307476  449388   
15   Hotel A1      Revenue     0  93622.5  156037.5  249660  312075  374490   

        2028  
3   177390.0  
0        0.0  
2   177390.0  
1   626778.0  
15  468112.5  
在您的解决方案中,需要将包含年份
2028
范围更改为
2029

df = pd.read_excel('test.xlsx')


df = (pd.wide_to_long(df, 
                      stubnames=[str(i) for i in range(2022,2029)],
                      i='Hotel Name', 
                      j='value', 
                      sep='',
                      suffix='.+')
                    .reset_index()
                   .sort_values('Hotel Name')
                   .drop('value', axis=1))
print (df.head())
   Hotel Name  2022     2023      2024    2025    2026    2027      2028
0     Hotel A     0  35478.0   59130.0   94608  118260  141912  177390.0
5     Hotel A     0      0.0       0.0       0       0       0       0.0
10    Hotel A     0  35478.0   59130.0   94608  118260  141912  177390.0
15    Hotel A     0  35478.0   94608.0  189216  307476  449388  626778.0
3    Hotel A1     0  93622.5  156037.5  249660  312075  374490  468112.5
我会在索引中隐藏酒店名称,然后将列更改为多索引,并堆叠:

df = pd.read_csv('test.csv', sep=';').set_index('Hotel Name')
df.columns = pd.MultiIndex.from_tuples([name.split(None, 1) for name in df.columns])
resul = df.stack()
它直接给出:

                         2022     2023      2024    2025     2026     2027       2028
Hotel Name                                                                           
Hotel A    Cost             0        0         0       0        0        0          0
           Cum. Profit      0    35478     94608  189216   307476   449388     626778
           Profit           0    35478     59130   94608   118260   141912     177390
           Revenue          0    35478     59130   94608   118260   141912     177390
Hotel B    Cost        -25000        0         0       0        0        0          0
           Cum. Profit -25000   116036    351096  727192  1197312  1761456    2466636
           Profit      -25000   141036    235060  376096   470120   564144     705180
           Revenue          0   141036    235060  376096   470120   564144     705180
Hotel B2   Cost             0        0         0       0        0        0          0
           Cum. Profit      0  34711,5     92564  185128   300833   439679   613236,5
           Profit           0  34711,5   57852,5   92564   115705   138846   173557,5
           Revenue          0  34711,5   57852,5   92564   115705   138846   173557,5
Hotel A1   Cost        -25000        0         0       0        0        0          0
           Cum. Profit -25000  68622,5    224660  474320   786395  1160885  1628997,5
           Profit      -25000  93622,5  156037,5  249660   312075   374490   468112,5
           Revenue          0  93622,5  156037,5  249660   312075   374490   468112,5
Hotel C    Cost        -25000        0         0       0        0        0          0
           Cum. Profit -25000    54935    188160  401320   667770   987510    1387185
           Profit      -25000    79935    133225  213160   266450   319740     399675
           Revenue          0    79935    133225  213160   266450   319740     399675

始终可以使用自定义顺序对多索引进行排序,方法是将其作为元组的一个iterable进行处理,并使用带键的标准
sorted
函数:

resul = resul.loc[sorted(resul.index, key=lambda x:
                         (x[0], ['Revenue', 'Cost', 'Profit', 'Cum. Profit'].index(x[1])))]
然后给出:

                         2022     2023      2024    2025     2026     2027       2028
Hotel Name                                                                           
Hotel A    Revenue          0    35478     59130   94608   118260   141912     177390
           Cost             0        0         0       0        0        0          0
           Profit           0    35478     59130   94608   118260   141912     177390
           Cum. Profit      0    35478     94608  189216   307476   449388     626778
Hotel A1   Revenue          0  93622,5  156037,5  249660   312075   374490   468112,5
           Cost        -25000        0         0       0        0        0          0
           Profit      -25000  93622,5  156037,5  249660   312075   374490   468112,5
           Cum. Profit -25000  68622,5    224660  474320   786395  1160885  1628997,5
Hotel B    Revenue          0   141036    235060  376096   470120   564144     705180
           Cost        -25000        0         0       0        0        0          0
           Profit      -25000   141036    235060  376096   470120   564144     705180
           Cum. Profit -25000   116036    351096  727192  1197312  1761456    2466636
Hotel B2   Revenue          0  34711,5   57852,5   92564   115705   138846   173557,5
           Cost             0        0         0       0        0        0          0
           Profit           0  34711,5   57852,5   92564   115705   138846   173557,5
           Cum. Profit      0  34711,5     92564  185128   300833   439679   613236,5
Hotel C    Revenue          0    79935    133225  213160   266450   319740     399675
           Cost        -25000        0         0       0        0        0          0
           Profit      -25000    79935    133225  213160   266450   319740     399675
           Cum. Profit -25000    54935    188160  401320   667770   987510    1387185

请分享您尝试过的内容。这有点不同,您需要结尾的数字才能使用
wide\u to\u long
@Cohan:添加了我的尝试这很有帮助。但我真的很想要我在“输出表”中给出的格式,其中年份是标题和成本、利润等单独的一行。@GKS-答案是按照正确的顺序为第一个解决方案编辑的。这是很棒的@SergeBallesta。有人想维持秩序吗?就像第二栏中的收入、成本、利润和利润一样?@GKS:这就足够对指数进行排序了。请看我的编辑。