在 Pandas 中过滤分组的 DataFrame

Posted

技术标签:

【中文标题】在 Pandas 中过滤分组的 DataFrame【英文标题】:Filtering grouped DataFrame in Pandas 【发布时间】:2012-10-21 11:15:02 【问题描述】:

我正在从 Pandas DataFrame 创建一个 groupby 对象,并希望选择所有大小大于 1 的组。

例子:

     A  B
0  foo  0
1  bar  1
2  foo  2
3  foo  3

以下似乎不起作用:

grouped = df.groupby('A')
grouped[grouped.size > 1]

预期结果:

A
foo 0
    2
    3

【问题讨论】:

给我们一个具体的例子,并展示你的尝试。 希望有所帮助:grouped.size().apply(lambda x: x>1),但我不知道该怎么做 github.com/pydata/pandas/issues/919 这很有趣..对于一个改变,我遇到了一个我需要的功能在 Pandas 中缺失的区域..长期以来,我对它的理解是缺失的..很棒的库是为了什么我愿意.. 【参考方案1】:

从 pandas 0.12 开始,您可以这样做:

>>> grouped.filter(lambda x: len(x) > 1)

     A  B
0  foo  0
2  foo  2
3  foo  3

【讨论】:

这种情况下的“x”是什么?那是指您过去分组的列吗? x 将是 groupby 操作的每个子组,您可以使用 grouped.groups 检查。在多列 groupby 的情况下,这些子组引用多个列,但这无关紧要,因为 len 按 pandas 对象中的行计数。 有没有办法在过滤后获取 GroupBy 对象,而不是 DataFrame?我现在看到的唯一方法是再次调用 groupby,但这似乎效率低下 @IvanVirabyan 更糟糕的是,空组再次弹出分类值。 grouped.filter(lambda x: len(x.index) > 1) 应该稍微快一点【参考方案2】:

我发现transform 对于非常大的数据帧比filter 更有效率:

element_group_sizes = df['A'].groupby(df['A']).transform('size')
df[element_group_sizes>1]

或者,在一行中:

df[df['A'].groupby(df['A']).transform('size')>1]

【讨论】:

很好的答案!只有你注重效率。太棒了! 不应该是element_group_sizes = df['A'].groupby('A')['A'].transform('size')吗? @IgorFobia no -- df['A'] 将是一个系列,将不再有一个列 'A'。我想element_group_sizes = df.groupby('A')['A'].transform('size') 会起作用。【参考方案3】:

如果您仍需要解决方法:

In [49]: pd.concat([group for _, group in grouped if len(group) > 1])
Out[49]: 
     A  B
0  foo  0
2  foo  2
3  foo  3

【讨论】:

:谢谢:这就是我现在已经实现的,但如果知道如何对分组对象进行过滤,因为这将独立于为每个自定义过滤案例编写新的列表理解,那就太好了。跨度> 一旦有人实施了上面提到的问题 #919,它会是一个很好的解决方案【参考方案4】:

你可以使用方法filter和属性shape

df.groupby('A').filter(lambda x: x.shape[0] > 1)

【讨论】:

以上是关于在 Pandas 中过滤分组的 DataFrame的主要内容,如果未能解决你的问题,请参考以下文章

Pandas | 18 GroupBy 分组

Pandas Dataframe 中分组的多重聚合

pandas使用groupby函数基于指定分组变量对dataframe数据进行分组使用size函数计算分组数据中每个分组样本的个数

在 Pandas 中使用条件列表过滤 DataFrame

pandas使用groupby函数基于指定分组变量对dataframe数据进行分组len函数和nunique函数计算分组的个数(分组包含多个dataframe)

将字典嵌套在另一个字典中,按 Pandas Dataframe 中的值分组