在DataFrame中查找具有一个差异的行

时间:2018-11-22 13:54:00

标签: pandas dataframe duplicates

我有一个数据集,其中行数几乎相同,这意味着除了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”的重复行。

2 个答案:

答案 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