python:如何融化保留特定顺序/自定义排序的数据框

Chr*_*ris 3 python dataframe pandas

我有一个数据框 df

Cat  B_1 A_2 C_3
A      1   2   3
B      4   5   6
C      7   8   9
Run Code Online (Sandbox Code Playgroud)

我想将其转换为数据框,以便 Label 列中的行遵循每个类别的 df 列的顺序。

Desired output

    Cat Label Value
    A     B_1    1
    A     A_2    2
    A     C_3    3
    B     B_1    4
    B     A_2    5
    B     C_3    6
    C     B_1    7
    C     A_2    8
    C     C_3    9  
Run Code Online (Sandbox Code Playgroud)

当我尝试

pd.melt(df, id_vars=["Cat"], var_name="Label",value_name="Value")
Run Code Online (Sandbox Code Playgroud)

我在标签列中丢失了所需的顺序,结果排序如下,

Cat Label Value
A     B_1    1
B     B_1    4
C     B_1    7
A     A_2    2
...
Run Code Online (Sandbox Code Playgroud)

可以在熔化函数中强制指定所需的行顺序吗?如果没有的话,如何实现这种自定义排序呢?


更新

我重命名了标签,因为它们不遵循字母顺序,因此简单的排序不起作用

sac*_*cuL 6

IIUC,您可以使用完全相同的代码并添加.sort_values('Cat'),或更简单:

df.melt('Cat',var_name='Label',value_name='Value').sort_values('Cat')

  Cat Label  Value
0   A   L_1      1
3   A   L_2      2
6   A   L_3      3
1   B   L_1      4
4   B   L_2      5
7   B   L_3      6
2   C   L_1      7
5   C   L_2      8
8   C   L_3      9
Run Code Online (Sandbox Code Playgroud)

如果您想以自定义方式对其进行排序(在下面的示例中,B先于A,先于C),那么您可以将其设置Cat为有序分类:

melted = df.melt('Cat',var_name='Label',value_name='Value')

melted['Cat'] = pd.Categorical(melted['Cat'], categories=['B','A','C'], ordered=True)

melted.sort_values('Cat')

  Cat Label  Value
1   B   L_1      4
4   B   L_2      5
7   B   L_3      6
0   A   L_1      1
3   A   L_2      2
6   A   L_3      3
2   C   L_1      7
5   C   L_2      8
8   C   L_3      9
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用stack,但随后您必须处理烦人的列重命名:

df.set_index('Cat').stack().reset_index().rename(columns={'level_1':'Label', 0:'Value'})

  Cat Label  Value
0   A   L_1      1
1   A   L_2      2
2   A   L_3      3
3   B   L_1      4
4   B   L_2      5
5   B   L_3      6
6   C   L_1      7
7   C   L_2      8
8   C   L_3      9
Run Code Online (Sandbox Code Playgroud)