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:这就足够对指数进行排序了。请看我的编辑。