如何使用多个变量名称和值来融合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循环迭代的一般方法。我看到了这个question和this,但他们没有帮助!
答案 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'])