在保留组的同时在Pandas中的GroupBy之后过滤组

时间:2018-04-14 13:07:32

标签: python pandas pandas-groupby

在pandas中我想做的事: df.groupby('A').filter(lambda x: x.name > 0) - 按列A分组,然后过滤名称为非正数的组。但是,这会取消分组,因为GroupBy.filter会返回DataFrame,从而丢失分组。我想按此顺序执行此操作,因为它的计算要求较低,因为filter后跟groupby会使DataFrame两次没有(先过滤然后分组)?同时从分组中克隆组(到字典或其他东西)将失去我无缝返回数据框的功能(如.filter的示例,您直接获得DataFrame

由于

示例:

   A  B
1 -1  1
2 -1  2
3  0  2
4  1  1
5  1  2

df.groupby('A')

GroupBy object
-1 : [1, 2]
 0 : [3]
 1 : [4,5]

GroupBy.filter(lambda x: x.name >= 0)

GroupBy object
 0 : [3]
 1 : [4,5]

4 个答案:

答案 0 :(得分:2)

让我们运行一些时间。

df = pd.DataFrame({'A':np.random.randint(-10,10,1000000),'B':np.random.random(1000000)})

两种回报的看法相等

df1 = df.groupby('A').filter(lambda x: x.name >= 0)
df2 = df[df.A >= 0]

all(df1 == df2)
True

时序:

%timeit df1 = df.groupby('A').filter(lambda x: x.name >= 0)
  

每回路607 ms±10.2 ms(平均值±标准偏差,7次运行,每次1次循环)

%timeit df2 = df[df.A >= 0]
  

每回路59.7 ms±724μs(平均值±标准偏差,7次运行,每次10次循环)

@jacquot解决方案比分组然后过滤快10倍。

答案 1 :(得分:1)

使用groupby实际上并不以任何方式聚合值。它只是创建分组,因此filter基本上是对原始数据帧进行过滤。我不认为你通过先分组来节省时间或计算,除非通过将一个函数应用于组来实现name值。

因此我推荐像

这样的东西
df.where(df.name > 0).groupby('A')  # now apply some transformation to the groups

答案 2 :(得分:1)

我认为先前的答案提出了解决方法,这可能对您有用,但不能回答问题。

您创建了组,并且想要基于组统计信息丢弃或保留一些组,然后对组执行您实际关心的一些组统计。这应该是可能的,并且在许多情况下很有用,但是,据我所知,现在仅当您因此使用两个相同的groupby时,才不可能将它作为链接命令。

让我们举个例子:Groupby揭示了一些不能在项目级别基础上过滤的功能(因此,不能选择以前的过滤)。例如,一组和。过滤器的麻烦之处在于,它返回一个数据帧而不是保留分组,并允许您对组进行进一步的计算。

这里是一个例子:

假设您要按'C'分组并按组(<700)中的'A'的总和进行过滤,但是实际上,在过滤后的组中,您实际上要关注这些组的标准性。如果filter仅是组的过滤器,那么它将起作用:

df.groupby(['C']).filter(lambda x:x['A'].sum()<700, combine=False).std()

这不起作用(请注意过滤器上不存在的combine=False选项),这是什么:

df.groupby(['C']).filter(lambda x:x['A'].sum()<700).groupby(['C']).std()

过滤器实际执行的是filter&combine,它遵循split-apply-combine逻辑。

答案 3 :(得分:0)

我理解像petsol而不是Scott那样的问题, 因此,斯科特给出的示例的等价性应该是:

df = d.DataFrame({'A':np.random.randint(-10,10,1000000),'B':np.random.random(1000000)})
df1 = df.groupby('A').filter(lambda x: x['A'].mean()>0).groupby('A').count()

而第二种方法显然行不通。

但是,在这里找到此解决方案之前,我只是简单地认为它是: Groupby对象是否具有类似于.iloc的DataFrames方法?

这样,当您创建Groupby对象时,您可以通过应用带有某些聚合函数的条件(并将其存储为索引对应于每个组的布尔值)来创建过滤器,然后仅在要求的团体。

不幸的是,我没有找到任何等效于iloc的有用方法或函数(我检查了“ nth”,“ take”和“ get_group”,但没有一个起作用)。