如何融合0和1的数据帧并仅保留1

Bri*_*ice 3 python dataframe pandas

这是我的原始数据框:

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
Run Code Online (Sandbox Code Playgroud)

我的目标是将变量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
Run Code Online (Sandbox Code Playgroud)

第三行重复两次,因为它有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)
Run Code Online (Sandbox Code Playgroud)

我的问题是我的DataFrame更大了,大多数值都是0。在删除第二行中的大多数行之前,创建第一个melt_DF会占用过多的内存。有没有一种方法可以仅在1s上应用熔化以节省内存?

Sco*_*ton 6

Let's try using set_index, stack, and mask:

df.set_index(['Label 1', 'Label 2', 'Label 3'], inplace=True)
df = df.mask(df == 0).stack().reset_index()
df
Run Code Online (Sandbox Code Playgroud)

Output:

   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
Run Code Online (Sandbox Code Playgroud)

并且,进行一些列重命名和清理以匹配预期的输出:

df.mask(df1 == 0).rename_axis('Variable', axis=1).stack().reset_index().drop(0, axis=1)
Run Code Online (Sandbox Code Playgroud)

输出:

   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
Run Code Online (Sandbox Code Playgroud)