【问题标题】:use group by to get n smallest values but with duplicates使用 group by 来获取 n 个最小值但有重复项
【发布时间】:2020-08-06 11:06:19
【问题描述】:

假设我有这样的 pandas DataFrame:

>>> df = pd.DataFrame({'id':[1,1,1,1,1,2,2,2,2,2,2,3,4],'value':[1,1,1,1,3,1,2,2,3,3,4,1,1]})
>>> df
id  value
1      1
1      1
1      1
1      1
1      3
2      1
2      2
2      2
2      3
2      3
2      4
3      1
4      1

我想为每个 id 包括重复项获取一个具有前 2 个(实际上是 n 个值)值的新 DataFrame,如下所示:

   id  value
0   1      1
1   1      1
3   1      1
4   1      1
5   1      3
6   2      1
7   2      2
8   2      2
9   3      1
10  4      1

我尝试过使用 head() 和 nsmallest() 但我认为它们不会包含重复项。有没有更好的方法来做到这一点?

进行编辑以明确表示如果重复项超过 2 个,我希望每组有 2 个以上的记录

【问题讨论】:

    标签: python pandas greatest-n-per-group


    【解决方案1】:

    第一步使用DataFrame.drop_duplicates,然后获取最高值,最后使用DataFrame.merge

    df1 = df.drop_duplicates(['id','value']).sort_values(['id','value']).groupby('id').head(2)
    df = df.merge(df1)
    print (df)
       id  value
    0   1      1
    1   1      1
    2   1      2
    3   1      2
    4   2      1
    5   2      2
    6   2      2
    7   3      1
    8   4      1
    

    df = pd.DataFrame({'id':[1,1,1,1,1,2,2,2,2,2,2,3,4],'value':[1,1,1,1,3,1,2,2,3,3,4,1,1]})
        
    df1 = df.drop_duplicates(['id','value']).sort_values(['id','value']).groupby('id').head(2)
    df = df.merge(df1)
    print (df)
       id  value
    0   1      1
    1   1      1
    2   1      1
    3   1      1
    4   1      3
    5   2      1
    6   2      2
    7   2      2
    8   3      1
    9   4      1
    

    或者使用 GroupBy.transform 的自定义 lambda 函数并在 boolean indexing 中过滤:

    df = df[df.groupby('id')['value'].transform(lambda x: x.isin(sorted(set(x))[:2]))]
    print (df)
        id  value
    0    1      1
    1    1      1
    2    1      2
    3    1      2
    5    2      1
    6    2      2
    7    2      2
    11   3      1
    12   4      1
    

    df = df[df.groupby('id')['value'].transform(lambda x: x.isin(sorted(set(x))[:2]))]
    print (df)
        id  value
    0    1      1
    1    1      1
    2    1      1
    3    1      1
    4    1      3
    5    2      1
    6    2      2
    7    2      2
    11   3      1
    12   4      1
    

    【讨论】:

    • 如果有 3 个 ID = 1 和 Value = 1,这是否会捕获它们?还是像 50?
    • @Jogianni - 我的解决方案每组获得前 2 个唯一值且有重复项,您还需要别的吗?
    猜你喜欢
    • 2020-06-24
    • 1970-01-01
    • 1970-01-01
    • 2017-12-31
    • 2018-10-22
    • 2019-04-02
    • 1970-01-01
    • 2013-06-27
    • 1970-01-01
    相关资源
    最近更新 更多