【问题标题】:Removing all rows of a duplicate based on value of multiple columns根据多列的值删除重复的所有行
【发布时间】:2014-10-16 20:35:16
【问题描述】:

我有一个包含多列和多行 (200k) 的大型数据框。我按组变量对行进行排序,每个组可以有一个或多个条目。每个组的其他列应该具有相同的值,但在某些情况下它们不会。它看起来像这样:

group   name    age    color
1       Anton   50     orange
1       Anton   21     red
1       Anton   21     red
2       Martin  78     black
2       Martin  78     blue
3       Maria   25     red
3       Maria   29     pink
4       Jake    33     blue

如果组的所有行的年龄或颜色都不相同,我想删除组的所有条目。(表示观察错误)但是,如果所有列都具有相同的值,我想保留重复的条目。 所以我希望的输出是:

group   name    age    color   
2       Martin  78     black
2       Martin  78     blue  
4       Jake    33     blue

在类似的情况下,我使用了这个函数,它运行得非常快: df = df.groupby('group').filter(lambda x: x.count() == 1)

但是,这不允许我检查列的值(年龄、颜色)。 我一直在玩 groupby 功能,但似乎无法掌握它。

/e:我刚刚意识到我错过了我的问题中的一个重要条件:如果一个或多个 SPECIFIC 列具有重复值,我只想删除观察结果。但是,其他列可能会有所不同。在上面的示例中,假设我不关心组内颜色之间是否存在差异,而只想检查年龄是否具有不同的值。(我编辑了示例以反映这一点)。我的实际情况更普遍并包含更多列,所以我想要例如在删除观察时检查几列并忽略其他列。

【问题讨论】:

    标签: python pandas group-by duplicates dataframe


    【解决方案1】:

    您可以使用计数器的字典来解决这个问题。

    from collections import defaultdict, Counter
    
    N = int(input())#read number of tuples
    mapGroupAge = defaultdict(Counter)#a dict of counters to count 
                                      #the repetitions by group
    
    for _ in range(N):
        # read tuples (from standard input in this example)
        group,name,age,color = input().split()
        #build the map (dict) indexed by the groups i.e. a key is a pair (group,name)
        mapGroupAge[(group,name)][(age,color)] += 1
    
    for (group,name), counter in mapGroupAge.items():
        # if all ages and colors for the same group are the same
        if(len(counter)==1):
            age,color = list(counter.keys())[0]
            # print all the repetitions
            for _ in range(counter[(age,color)]):
                print(group, name, age,color)
    

    您可以通过执行上面的代码并将以下行粘贴到标准输入中来测试上面的代码:

    8
    1       Anton   50     orange
    1       Anton   21     red
    1       Anton   21     red
    2       Martin  78     blue
    2       Martin  78     blue
    3       Maria   25     red
    3       Maria   25     pink
    4       Jake    33     blue
    

    如你所愿,执行结果是:

    2 Martin 78 blue
    2 Martin 78 blue
    4 Jake 33 blue
    

    【讨论】:

      【解决方案2】:

      虽然@ismax 的答案可行,但您可以使用与.count() 解决方案类似的模式,但先删除重复项。

      In [229]: In [179]: df.groupby('group').filter(lambda x: len(x.drop_duplicates(subset=['age'])) == 1)
      Out[229]: 
         group    name  age  color
      3      2  Martin   78  black
      4      2  Martin   78   blue
      7      4    Jake   33   blue
      

      【讨论】:

      • 这接近我想要的。但是我才意识到我的问题不够精确。我对其进行了编辑以更准确地反映我的具体情况。
      • @cover51 - 查看编辑,只需将列传递给 subset 参数。
      猜你喜欢
      • 2016-07-27
      • 2022-06-27
      • 2019-05-29
      • 1970-01-01
      • 1970-01-01
      • 2021-06-24
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      相关资源
      最近更新 更多