поиск строк с одним отличием в DataFrame - PullRequest
0 голосов
/ 22 ноября 2018

У меня есть набор данных, в котором количество строк почти одинаково, то есть они имеют одинаковые значения для всех полей, кроме столбца 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, но внутри столбца CI нужно только найти комбинации «Rep» и «Dem».Поэтому я не хочу, чтобы 2 одинаковые строки со столбцом C, например, «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 голосов
/ 22 ноября 2018

Получить все столбцы без C с помощью difference для отображения в списке, затем sort_values для столбца C и преобразовать его в tuples для групп.Последняя join к оригиналу, сравнение по Rep,Dem и фильтрация по boolean indexing:

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 с,но если это возможно, потому что несколько одинаковых значений для групп, таких как Rep,Dem,Dem, возможно цепное условие с size:

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
0 голосов
/ 22 ноября 2018

Вы можете использовать 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
...