我有一个数据集,其中行数几乎相同,这意味着除了C列外,所有字段的值都相同。
A B C D ..... Z
0 50 'Ohio' 'Rep' 3 45
1 50 'Ohio' 'Dem' 3 45
2 40 'Kansas' 'Dem' 34 1
3 30 'Kansas' 'Dem' 45 2
4 55 'Texas' 'Rep' 2 7
....
38 55 'Texas' 'Dem' 2 7
除了列C,我想标识所有相同的行,但是在列C中,我只想找到“ Rep”和“ Dem”的组合。因此,我不希望C列有2个相同的行,例如'Rep'和'Rep'。
A B C D ......Z
0 50 'Ohio' 'Rep' 3 45
1 50 'Ohio' 'Dem' 3 45
4 55 'Texas' 'Rep' 2 7
38 55 'Texas' 'Dem' 2 7
我在所有列(但C)上使用了重复的方法,该方法提供了所有相同的行。但是,这不会导致重复,其中每个带有“ Rep”的重复行都恰好具有一个带有“ Dem”的重复行。
答案 0 :(得分:1)
您可以将duplicated
与参数keep
一起使用来False
为删除列c
的重复行创建掩码,并使用isin
过滤其中包含['Rep','Dem']
中任何一个的行:
mask = df.drop(['C'], axis = 1).duplicated(keep=False)
df[mask][df['C'].isin(['Rep','Dem'])].drop_duplicates()
A B C D Z
0 50 'Ohio' 'Rep' 3 45
1 50 'Ohio' 'Dem' 3 45
4 55 'Texas' 'Rep' 2 7
5 55 'Texas' 'Dem' 2 7
答案 1 :(得分:1)
通过difference
列出所有没有C
的列,然后每列C
sort_values
并将其转换为每组tuples
。最后join
到原始的boolean indexing
,然后按Rep,Dem
比较,然后按size
进行过滤:
cols = df.columns.difference(['C']).tolist()
s = df.sort_values('C').groupby(cols)['C'].apply(tuple).rename('m') == ('Dem','Rep')
df = df[df.join(s, on=cols)['m']]
另一种解决方案是按set
s进行比较,但是如果可能的话,因为{{3}}可能导致每个组(例如Rep,Dem,Dem
)具有多个相同的值:
g = df.groupby(cols)['C']
m1 = g.transform('size') == 2
m2 = g.transform(lambda x: set(x) == set(['Rep','Dem']))
df = df[m1 & m2]
print (df)
A B C D Z
0 50 'Ohio' Rep 3 45
1 50 'Ohio' Dem 3 45
4 55 'Texas' Rep 2 7
38 55 'Texas' Dem 2 7