如何基于三个变量将宽数据转换为长数据

2024-03-29 02:01:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我有这样一个数据帧结构:

Item FY20 FY21 FY22 ...  
Case High Low Base
Multiple 1.2 2.3 3.4
Cash 1.1 1.4 1.2

我需要这样的数据:

Item Date Case Value
Cash FY20 High 1.1
Cash FY21 Low 1.4
Cash FY22 Base 1.2

因此,我基本上是想将数据从宽格式转换为基于“Case”、“FY”和项的长格式。你知道吗

我已经试过使用多个索引了,而且还把它弄得乱七八糟pd.枢轴但我真的被难住了。你知道吗


Tags: 数据basedatevalue格式cashmultipleitem
2条回答

让我们从创建源数据帧开始:

df = pd.DataFrame(data=[
    [ 'Item',     'FY20', 'FY21', 'FY22' ],
    [ 'Case',     'High', 'Low',  'Base' ],
    [ 'Multiple', 1.2,    2.3,    3.4    ],
    [ 'Cash',     1.1,    1.4,    1.2    ]])

结果是:

          0     1     2     3
0      Item  FY20  FY21  FY22
1      Case  High   Low  Base
2  Multiple   1.2   2.3   3.4
3      Cash   1.1   1.4   1.2

那么我们必须:

  • 转置此数据帧
  • 将第一行转换为列名
  • 更改第一列名称:

为此,请运行:

df2 = df.transpose()
df2.columns = df2.iloc[0].tolist()
df2.drop(index=0, inplace=True)
df2.rename(columns={'Item': 'Date'})

结果是:

   Date  Case Multiple Cash
1  FY20  High      1.2  1.1
2  FY21   Low      2.3  1.4
3  FY22  Base      3.4  1.2

要获得结果,请运行:

df2.melt(id_vars=['Date', 'Case'], value_vars=['Cash'],
    var_name='Name', value_name='Value')

您将收到:

   Date  Case  Name Value
0  FY20  High  Cash   1.1
1  FY21   Low  Cash   1.4
2  FY22  Base  Cash   1.2

或者结果应该包括多个柱的熔化? 为此,请删除value\u vars=['Cash']。 这种方式将包括所有剩余的列(除 包含在id变量中。你知道吗

IIUC,您可以使用这段代码重塑您的数据帧:

df.set_index('Item')\ # move Item into dataframe index
  .T\  # transpose dataframe
  .rename_axis('Date')\  #rename index to Date
  .reset_index()\  #move index into dataframe as column
  .melt(['Date', 'Case'])  #melt dataframe to get to long format

输出:

   Date  Case      Item value
0  FY20  High  Multiple   1.2
1  FY21   Low  Multiple   2.3
2  FY22  Base  Multiple   3.4
3  FY20  High      Cash   1.1
4  FY21   Low      Cash   1.4
5  FY22  Base      Cash   1.2

详情:

其中df是:

       Item  FY20 FY21  FY22
0      Case  High  Low  Base
1  Multiple   1.2  2.3   3.4
2      Cash   1.1  1.4   1.2

df.set_index('Item').T  

快到了

Item  Case Multiple Cash
FY20  High      1.2  1.1
FY21   Low      2.3  1.4
FY22  Base      3.4  1.2

df.set_index('Item').T.rename_axis('Date').reset_index()

添加rename\u axis和reset\u index为melt准备数据帧

Item  Date  Case Multiple Cash
0     FY20  High      1.2  1.1
1     FY21   Low      2.3  1.4
2     FY22  Base      3.4  1.2

最后一个数据帧:

df.set_index('Item').T.rename_axis('Date').reset_index().melt(['Date', 'Case'])

输出:

   Date  Case      Item value
0  FY20  High  Multiple   1.2
1  FY21   Low  Multiple   2.3
2  FY22  Base  Multiple   3.4
3  FY20  High      Cash   1.1
4  FY21   Low      Cash   1.4
5  FY22  Base      Cash   1.2

如果你只想要“现金”记录,那就用这个

df_out = df.set_index('Item').T.rename_axis('Date').reset_index().melt(['Date', 'Case'])
df_out.query('Item == "Cash"')

输出:

   Date  Case  Item value
3  FY20  High  Cash   1.1
4  FY21   Low  Cash   1.4
5  FY22  Base  Cash   1.2

相关问题 更多 >