【问题标题】:Pandas, filter by count熊猫,按计数过滤
【发布时间】:2020-01-13 00:23:06
【问题描述】:

我正在尝试按 id 的出现次数过滤数据框。

id    date
1     2018-05-06
1     2018-05-08
1     2018-05-11
2     2018-06-02
2     2018-06-16
3     2018-06-04
3     2018-06-09
4     2018-06-06
4     2018-06-11
4     2018-06-17

我想过滤出现 3 次的 id 值,因此过滤后的数据框应如下所示:

id    date
1     2018-05-06
1     2018-05-08
1     2018-05-11
4     2018-06-06
4     2018-06-11
4     2018-06-17

我之前曾尝试使用以下代码,该代码来自另一个 StackOverflow 帖子。代码一开始可以,但是大约半小时后我使用它时,它给了我错误“lambda cannot contain assignment”:

graphview3 = df.groupby('id').filter(lambda x: x['id'].count()=3)

我不知道为什么这段代码以前有效,现在给我这个错误。有什么帮助吗?

【问题讨论】:

    标签: python pandas lambda group-by


    【解决方案1】:

    我认为您需要比较每个组的长度:

    graphview3 = df.groupby('id').filter(lambda x: len(x) == 3)
    

    或将GroupBy.transformsizeboolean indexing 一起使用:

    graphview3 = df[df.groupby('id')['id'].transform('size') == 3]
    print (graphview3)
       id        date
    0   1  2018-05-06
    1   1  2018-05-08
    2   1  2018-05-11
    7   4  2018-06-06
    8   4  2018-06-11
    9   4  2018-06-17
    

    在您的解决方案中,需要使用双倍 == 进行比较,更常见的 Series.count 用于排除 NaNs 的计数值(但在这里它工作得很好,因为 groupby 默认使用 NaN 删除行s 在id):

    graphview3 = df.groupby('id').filter(lambda x: x['id'].count()==3)
    

    【讨论】:

    • 谢谢!你知道为什么我之前使用的代码在某一时刻工作,然后给我“lambda 不能包含赋值”错误吗?”
    • @bbk611 - 当然,=3 中只有一个=,但需要==3
    • 那是我的愚蠢。没有意识到这是一个布尔值。谢谢。
    【解决方案2】:
    graphview3 = df.loc[df['id'].map(df['id'].value_counts()) == 3]
    

    【讨论】:

    • 谢谢!我需要学习如何编写更快、更高效的代码。这个方法比下面的 len() 和 transform() 方法快吗?
    • 在我的机器上,我的是 2.14ms,来自 Jezrael 的是 2.77 & 2.3 。我认为你应该在你的机器上为你的完整数据帧计时,然后再决定。
    猜你喜欢
    • 2019-04-13
    • 2018-08-09
    • 2017-12-15
    • 2016-05-05
    • 1970-01-01
    • 1970-01-01
    • 2019-01-13
    • 1970-01-01
    • 2015-07-02
    相关资源
    最近更新 更多