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

时间:2019-05-30 16:49:09

标签: python pandas

我有一个结构如下的数据框:

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.pivot有点混乱,但是老实说,我在这里很困惑。

2 个答案:

答案 0 :(得分:0)

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_axis和reset_index以准备用于熔化的数据框,

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

答案 1 :(得分:0)

让我们从创建源DataFrame开始:

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

或者结果可能还包括 Multiple 列的融合? 为此,请删除 value_vars = ['Cash'] 。 这样,熔化将包括所有剩余列( 包含在 id_vars 中。)