Python 基于多列的值删除副本的所有行
我有一个包含多列和多行的大型数据框(200k)。我通过一个组变量对行进行排序,每个组可以有一个或多个条目。每组的其他列应具有相同的值,但在某些情况下,它们不具有相同的值。看起来是这样的:Python 基于多列的值删除副本的所有行,python,pandas,group-by,duplicates,dataframe,Python,Pandas,Group By,Duplicates,Dataframe,我有一个包含多列和多行的大型数据框(200k)。我通过一个组变量对行进行排序,每个组可以有一个或多个条目。每组的其他列应具有相同的值,但在某些情况下,它们不具有相同的值。看起来是这样的: group name age color 1 Anton 50 orange 1 Anton 21 red 1 Anton 21 red 2 Martin 78 black 2 Martin
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:我刚刚意识到我的问题中遗漏了一个重要条件:我只想删除观察值,如果一个或多个特定列有重复的值。但是,其他列可以不同。在上面的示例中,假设我不关心组内颜色之间是否存在差异,但只想检查年龄是否具有不同的值。(我编辑示例以反映这一点)。我的实际案例更一般,包含更多列,因此,我想检查一些列,在删除观察值时忽略其他列。您可以使用一组计数器来解决这个问题
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
虽然@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-请参见编辑,只需将列传递给
子集
参数即可。