使用groupby的结果过滤pandas数据帧

lau*_*rup 8 python filter dataframe python-2.7 pandas

我有一个大型数据框(40M行),如果值满足groupby对象中的条件,我想基于一列过滤掉行.

例如,这是一些随机数据.'letter'列实际上有数千个唯一值:

     x   y   z  letter
0   47  86  30  e
1   58   9  28  b
2   96  59  42  a
3   79   6  45  e
4   77  80  37  d
5   66  91  35  d
6   96  31  52  d
7   56   8  26  e
8   78  96  14  a
9   22  60  13  e
10  75  82   9  d
11   5  54  29  c
12  83  31  40  e
13  37  70   2  c
14  53  67  66  a
15  76  33  78  d
16  64  67  81  b
17  23  94   1  d
18  10   1  31  e
19  52  11   3  d
Run Code Online (Sandbox Code Playgroud)

在'letter'列上应用groupby,并获取每个字母的x列的总和:

df.groupby('letter').x.sum()
>>> a    227
    b    122
    c     42
    d    465
    e    297
Run Code Online (Sandbox Code Playgroud)

然后,我排序查看具有最高总和的字母,并手动识别阈值.在此示例中,阈值可能为200.

df.groupby('letter').x.sum().reset_index().sort_values('x', ascending=False)
>>> letter    x
3      d  465
4      e  297
0      a  227
1      b  122
2      c   42
Run Code Online (Sandbox Code Playgroud)

这是我被困的地方. 在原始数据框中,如果groupby的总和为'x'> 200,我想保留字母,并删除其他行.所以在这个例子中,它会将所有行保留为d,e或a.

我正在尝试这样的东西,但它不起作用:

df.groupby('letter').x.sum().filter(lambda x: len(x) > 200)
Run Code Online (Sandbox Code Playgroud)

即使我过滤groupby对象,我如何使用它来过滤原始数据帧?

Psi*_*dom 6

您可以使用groupby transform计算每行x的总和,并创建一个逻辑系列,其中包含您可以使用该条件执行子集的条件:

df1 = df[df.x.groupby(df.letter).transform('sum') > 200]

df1.letter.unique()
# array(['e', 'a', 'd'], dtype=object)
Run Code Online (Sandbox Code Playgroud)

或另一种选择使用groupby.filter:

df2 = df.groupby('letter').filter(lambda g: g.x.sum() > 200)

df2.letter.unique()
# array(['e', 'a', 'd'], dtype=object)
Run Code Online (Sandbox Code Playgroud)

  • 像魅力一样工作。谢谢你。你让我免于做一些非常非 Pythonic 的事情 (2认同)