融化pandas数据框,具有多个变量名和多个值名

时间:2017-08-13 16:16:35

标签: python pandas melt

如何使用多个变量名称和值来融合pandas数据框?我有以下数据框,在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

在for循环期间,数据框将包含不同数量的类及其概率。这就是为什么我正在寻找适用于所有for循环迭代的一般方法。我看到了这个questionthis,但他们没有帮助!

4 个答案:

答案 0 :(得分:12)

dict需要lreshape来指定类别:

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

编辑:

lreshape现在没有记录,但将来可能会删除(with pd.wide_to_long too)。

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

答案 1 :(得分:4)

或者你可以尝试使用 str.contain pd.concat




  DF1 = df2.loc [:,df2.columns.str.contains( '_ A |猫| ID')]
名称= [ 'ID', '猫', '级', '习题']&#XA ; DF1.columns =名
 DF2 = df2.loc [:,df2.columns.str.contains( '_乙|猫| ID')]
 DF2.columns =名
 pd.concat( [DF1,DF2],轴= 0)

输出[354]:
 ID Cat Class Prob
 0 1 Veg 1 0.9
 1 2 Veg 1 0.8
 2 3肉1 0.6
 3 4肉1 0.3
 4 5 Veg 1 0.2&# xA; 0 1 Veg 2 0.1
 1 2 Veg 2 0.2
 2 3肉2 0.4
 3 4肉2 0.7
 4 5 Veg 2 0.8
  



答案 2 :(得分:0)

最高投票答案使用未记录的lreshape,由于其与pd.wide_to_long的相似性而在某些时候可能会被弃用,该{{3}}已记录在案并可在此处直接使用。默认情况下,suffix仅与数字匹配。你必须改变它以匹配字符(这里我只使用了任何字符)。

pd.wide_to_long(df, stubnames=['Class', 'Prob'], i=['ID', 'Cat'], j='DROPME', suffix='.')\
  .reset_index()\
  .drop('DROPME', axis=1)

   ID   Cat  Class  Prob
0   1   Veg      1   0.9
1   1   Veg      2   0.1
2   2   Veg      1   0.8
3   2   Veg      2   0.2
4   3  Meat      1   0.6
5   3  Meat      2   0.4
6   4  Meat      1   0.3
7   4  Meat      2   0.7
8   5   Veg      1   0.2
9   5   Veg      2   0.8

答案 3 :(得分:0)

您也可以使用pd.melt

# Make DataFrame
df = pd.DataFrame({'ID' :  [i for i in range(1,6)],
                   'Cat' : ['Veg']*2 + ['Meat']*2 + ['Veg'],
                   'Class_A' : [1]*5,
                   'Class_B' : [2]*5,
                   'Prob_A' : [0.9, 0.8, 0.6, 0.3, 0.2],
                   'Prob_B' : [0.1, 0.2, 0.4, 0.7, 0.8]})

# Make class dataframe and prob dataframe
df_class = df.loc[:, ['ID', 'Cat', 'Class_A', 'Class_B']]
df_prob = df.loc[:, ['ID', 'Cat', 'Prob_A', 'Prob_B']]

# Melt class dataframe and prob dataframe
df_class = df_class.melt(id_vars = ['ID',
                                    'Cat'],
                         value_vars = ['Class_A',
                                       'Class_B'],
                         value_name = 'Class')
df_prob = df_prob.melt(id_vars = ['ID',
                                  'Cat'],
                       value_vars = ['Prob_A',
                                     'Prob_B'],
                       value_name = 'Prob')

# Clean variable column so only 'A','B' is left in both dataframes
df_class.loc[:, 'variable'] = df_class.loc[:, 'variable'].str.partition('_')[2]
df_prob.loc[:, 'variable'] = df_prob.loc[:, 'variable'].str.partition('_')[2]

# Merge class dataframe with prob dataframe on 'ID', 'Cat', and 'variable';
# drop 'variable'; sort values by 'ID', 'Cat'
final = df_class.merge(df_prob,
                       how = 'inner',
                       on = ['ID',
                             'Cat',
                             'variable']).drop('variable', axis = 1).sort_values(by = ['ID',
                                                                                       'Cat'])