这是我的原始数据框:
Label 1 | Label 2 | Label 3 | Variable 1 | Variable 2
-------------------------------------------------------
Blabla1 | Hop1 | Hip1 | 0 | 1
Blabla2 | Hop2 | Hip2 | 1 | 0
Blabla3 | Hop3 | Hip3 | 1 | 1
Blabla4 | Hop4 | Hip4 | 0 | 0
我的目标是将变量1和变量2放入一行,如果它们中有1。对于上面的示例,例外结果为:
Label 1 | Label 2 | Label 3 | Variable
------------------------------------------
Blabla1 | Hop1 | Hip1 | Variable 2
Blabla2 | Hop2 | Hip2 | Variable 1
Blabla3 | Hop3 | Hip3 | Variable 1
Blabla3 | Hop3 | Hip3 | Variable 2
第三行重复两次,因为它有2个变量,而第四行消失了,因为其中只有0。
我找到了一种可以使用pandas.melt
函数进行工作的解决方案:
melt_DF = df.melt(id_vars=['Label 1', 'Label 2', 'Label 3'], value_vars=['Variable 1', 'Variable 2'])
melt_DF = melt_DF[melt_DF['value'] == 1].drop(columns='value', axis=1)
我的问题是我的DataFrame更大了,大多数值都是0。在删除第二行中的大多数行之前,创建第一个melt_DF会占用过多的内存。有没有办法只在1s上应用融化以节省内存?
答案 0 :(得分:5)
让我们尝试使用set_index
,stack
和mask
:
df.set_index(['Label 1', 'Label 2', 'Label 3'], inplace=True)
df = df.mask(df == 0).stack().reset_index()
df
输出:
Label 1 Label 2 Label 3 level_3 0
0 Blabla1 Hop1 Hip1 Variable 2 1.0
1 Blabla2 Hop2 Hip2 Variable 1 1.0
2 Blabla3 Hop3 Hip3 Variable 1 1.0
3 Blabla3 Hop3 Hip3 Variable 2 1.0
然后,进行一些列重命名和清理以匹配预期的输出:
df.mask(df1 == 0).rename_axis('Variable', axis=1).stack().reset_index().drop(0, axis=1)
输出:
Label 1 Label 2 Label 3 Variable
0 Blabla1 Hop1 Hip1 Variable 2
1 Blabla2 Hop2 Hip2 Variable 1
2 Blabla3 Hop3 Hip3 Variable 1
3 Blabla3 Hop3 Hip3 Variable 2
答案 1 :(得分:0)
如果您实际上主要是零并且只有2个变量,那么以下逻辑应该非常有效:
这可以减少熔化的大小并输出很多,所以我希望它将为您解决问题。
答案 2 :(得分:0)
join
cols = ['Variable 1', 'Variable 2']
data, idx = zip(*[(v, i) for (i, v), a in df[cols].stack().items() if a != 0])
df.drop(cols, 1).join(pd.Series(data, idx, name='Variable'), how='right')
Label 1 Label 2 Label 3 Variable
0 Blabla1 Hop1 Hip1 Variable 2
1 Blabla2 Hop2 Hip2 Variable 1
2 Blabla3 Hop3 Hip3 Variable 1
2 Blabla3 Hop3 Hip3 Variable 2