Python 具有多个变量名和多个值名的数据帧

Python 具有多个变量名和多个值名的数据帧,python,pandas,melt,Python,Pandas,Melt,如何使用多个变量名和值来融化熊猫数据帧?我有下面的数据框,它在for循环中改变了它的形状。在一个for循环迭代中,它如下所示: ID Cat Class_A Class_B Prob_A Prob_B 1 Veg 1 2 0.9 0.1 2 Veg 1 2 0.8 0.2 3 Meat 1 2 0.6

如何使用多个变量名和值来融化熊猫数据帧?我有下面的数据框,它在for循环中改变了它的形状。在一个for循环迭代中,它如下所示:

ID  Cat    Class_A   Class_B     Prob_A     Prob_B
1   Veg      1        2          0.9         0.1
2   Veg      1        2          0.8         0.2
3   Meat     1        2          0.6         0.4
4   Meat     1        2          0.3         0.7
5   Veg      1        2          0.2         0.8
ID  Cat    Class     Prob    
1   Veg      1       0.9       
1   Veg      2       0.1
2   Veg      1       0.8        
2   Veg      2       0.2
3   Meat     1       0.6         
3   Meat     2       0.4
4   Meat     1       0.3         
4   Meat     2       0.7
5   Veg      1       0.2         
5   Veg      2       0.8
我需要把它融化成这样:

ID  Cat    Class_A   Class_B     Prob_A     Prob_B
1   Veg      1        2          0.9         0.1
2   Veg      1        2          0.8         0.2
3   Meat     1        2          0.6         0.4
4   Meat     1        2          0.3         0.7
5   Veg      1        2          0.2         0.8
ID  Cat    Class     Prob    
1   Veg      1       0.9       
1   Veg      2       0.1
2   Veg      1       0.8        
2   Veg      2       0.2
3   Meat     1       0.6         
3   Meat     2       0.4
4   Meat     1       0.3         
4   Meat     2       0.7
5   Veg      1       0.2         
5   Veg      2       0.8
在for循环期间,数据帧将包含不同数量的类及其概率。这就是为什么我要寻找一种适用于所有for循环迭代的通用方法。我看到了,但是他们没有帮助

您需要通过
dict
指定类别:

d = {'Class':['Class_A', 'Class_B'], 'Prob':['Prob_A','Prob_B']}
df = pd.lreshape(df,d)
print (df)
    Cat  ID  Class  Prob
0   Veg   1      1   0.9
1   Veg   2      1   0.8
2  Meat   3      1   0.6
3  Meat   4      1   0.3
4   Veg   5      1   0.2
5   Veg   1      2   0.1
6   Veg   2      2   0.2
7  Meat   3      2   0.4
8  Meat   4      2   0.7
9   Veg   5      2   0.8
更具活力的解决方案:

Class = [col for col in df.columns if col.startswith('Class')]
Prob = [col for col in df.columns if col.startswith('Prob')]
df = pd.lreshape(df, {'Class':Class, 'Prob':Prob})
print (df)
    Cat  ID  Class  Prob
0   Veg   1      1   0.9
1   Veg   2      1   0.8
2  Meat   3      1   0.6
3  Meat   4      1   0.3
4   Veg   5      1   0.2
5   Veg   1      2   0.1
6   Veg   2      2   0.2
7  Meat   3      2   0.4
8  Meat   4      2   0.7
9   Veg   5      2   0.8
编辑:

现在未记录,但将来可能会被删除()


可能的解决方案是将所有3个函数合并为一个-可能是
melt
,但现在还没有实现。也许是新版本的熊猫。然后我的答案将被更新。

或者您可以使用
str.contain
pd.concat

DF1=df2.loc[:,df2.columns.str.contains('_A|Cat|ID')]
name=['ID','Cat','Class','Prob']
DF1.columns=name
DF2=df2.loc[:,df2.columns.str.contains('_B|Cat|ID')]
DF2.columns=name
pd.concat([DF1,DF2],axis=0)

Out[354]: 
   ID   Cat  Class  Prob
0   1   Veg      1   0.9
1   2   Veg      1   0.8
2   3  Meat      1   0.6
3   4  Meat      1   0.3
4   5   Veg      1   0.2
0   1   Veg      2   0.1
1   2   Veg      2   0.2
2   3  Meat      2   0.4
3   4  Meat      2   0.7
4   5   Veg      2   0.8

得票最多的答案使用了未记录的
lreshape
,由于其与已记录的答案相似,可能在某些时候被弃用,并可直接在此处使用。默认情况下,后缀只与数字匹配。您必须将其更改为匹配字符(这里我只使用了任意字符)

你也可以使用


@杰兹雷尔:如果我需要在类下有类的名称(“Class_A”,“Class_B”)而不是它们的代码(“1”,“2”)?我认为最简单的是
df['Class_A']='Class_A'
df['Class_B']='Class_B'
-用标量替换列中的值,然后使用
lreshape
@jezrael我认为没有文档记录的函数不适合使用,因为您必须直接链接到源代码。有人说要删除
lreshape
@Ted Petrou-谢谢你的评论。是的,将来有时可能会删除或不删除功能,这两种功能很少使用。但我认为这不是否决投票的理由:(我认为这个答案真的很糟糕,这就是我否决它的原因。你仍然有10票赞成。在我看来,你几乎不应该使用未记录的功能,尤其是那些具有同等和更高级对应项的功能,如
pd.wide\u to\u long
。现在,人们开始讨论这个问题,并认为这是一种融合两种功能的正确方法umns。任何人都不可能在生产中使用它。