一次融化并过滤熊猫数据框

时间:2019-08-06 13:21:23

标签: python pandas dataframe

我有一个巨大的熊猫数据框,具有数百万行和数千列。 参见下面的示例。

X   Y   col_1   col_2   col_3   col_4   col_5   col_6   col_7   col_8   col_9   col_10
0   A   1   0   0   0   0   0   1   1   1   1   1
1   B   1   0   0   0   0   0   1   1   1   1   1
2   C   2   0   0   0   0   0   1   1   1   1   1
3   A   3   0   0   0   0   0   1   1   1   1   1

我想使用pd.meltX列上的Ycol_1上的col_10来融化数据框。我的原始数据框中将有更多列。

我可以这样,

pd.melt(s, ['X', 'Y'], [x for x in s.columns if x not in ['X', 'Y']])

融化之后,我将得到一个这样的数据框,

    X   Y   variable    value
0   A   1   col_1   0
1   B   1   col_1   0
2   C   2   col_1   0
3   A   3   col_1   0
4   A   1   col_2   0
5   B   1   col_2   0
6   C   2   col_2   0
7   A   3   col_2   0
8   A   1   col_3   0
9   B   1   col_3   0
10  C   2   col_3   0
11  A   3   col_3   0
12  A   1   col_4   0
13  B   1   col_4   0
14  C   2   col_4   0
15  A   3   col_4   0
16  A   1   col_5   0
17  B   1   col_5   0
18  C   2   col_5   0
19  A   3   col_5   0
20  A   1   col_6   1
21  B   1   col_6   1
22  C   2   col_6   1
23  A   3   col_6   1
24  A   1   col_7   1
25  B   1   col_7   1
26  C   2   col_7   1
27  A   3   col_7   1
28  A   1   col_8   1
29  B   1   col_8   1
30  C   2   col_8   1
31  A   3   col_8   1
32  A   1   col_9   1
33  B   1   col_9   1
34  C   2   col_9   1
35  A   3   col_9   1
36  A   1   col_10  1
37  B   1   col_10  1
38  C   2   col_10  1
39  A   3   col_10  1

我只是对值为1的行感兴趣,所以我会做

melted.loc[melted['value'] == 1]

仅获取所需的行。

但是,当我的数据如此之大时,我将出现内存不足错误,因为融化的数据会填满我的RAM并使其窒息。完全有道理。

我想在融化自身时根据变量进行过滤。像melt_filter之类的东西,这样我就不会用光内存。

在示例中,我在列col_6col_10上方显示了1,然后可以对其进行手工过滤然后融化。但这不是实际情况。我将有一些行将混合使用01。因此,我无法事先进行过滤。

是否可能这样?如果是,该怎么办??

编辑:许多注释说明了通过某种方式过滤数据并融化数据的方法。我不能这样做,因为在实际数据中,没有列将完全为0,没有列将完全为1。它将是0和1的混合。

1 个答案:

答案 0 :(得分:1)

更新 感谢@rafaelc的评论。我相信使用np.nonzero的此解决方案的内存效率更高:

cols = df.columns[2:]
nonzeros = np.nonzero(df[cols].values)

# nonzeros consist of two arrays
# nonzeros[0] is the row coordinates of nonzero values
# nonzeros[1] is the col coordinates of nonzero values

# all we need is to extract rows at ['X','Y'] 
# and corresponding columns
# for each nonzero value:
pd.concat((df.loc[nonzeros[0], df.columns[:2]].reset_index(drop=True),
           df.columns[nonzeros[1]].to_frame().reset_index(drop=True)
          ),
          axis=1
         )

输出(值部分并不重要,因为它始终为1):

    X   Y   0
0   A   1   col_4
1   A   1   col_5
2   A   1   col_6
3   A   1   col_7
4   A   1   col_8
5   B   1   col_4
6   B   1   col_5
7   B   1   col_6
8   B   1   col_7
9   B   1   col_8
10  C   2   col_4
11  C   2   col_5
12  C   2   col_6
13  C   2   col_7
14  C   2   col_8
15  A   3   col_4
16  A   3   col_5
17  A   3   col_6
18  A   3   col_7
19  A   3   col_8