Это немного сложно объяснить, но потерпите меня. Предположим, у нас есть следующий набор данных:
df = pd.DataFrame({'foo': [1, 1, 1, 8, 1, 5, 5, 5],
'bar': [2, float('nan'), 2, 5, 2, 3, float('nan'), 6],
'abc': [3, 3, 3, 7, float('nan'), 9, 9, 7],
'def': [4, 4, 4, 2, 4, 8, 8, 8]})
print(df)
>>>
foo bar abc def
0 1 2.0 3.0 4
1 1 NaN 3.0 4
2 1 2.0 3.0 4
3 8 5.0 7.0 2
4 1 2.0 NaN 4
5 5 3.0 9.0 8
6 5 NaN 9.0 8
7 5 6.0 7.0 8
Наша цель - найти все повторяющиеся строки. Однако некоторые из этих дубликатов неполные, поскольку имеют значения NaN. Тем не менее, мы хотим найти и эти дубликаты. Итак, ожидаемый результат:
foo bar abc def
0 1 2.0 3.0 4
1 1 NaN 3.0 4
2 1 2.0 3.0 4
4 1 2.0 NaN 4
5 5 3.0 9.0 8
6 5 NaN 9.0 8
Если мы попытаемся сделать это простым способом, это даст нам только полные строки:
print(df[df.duplicated(keep=False)])
>>>
foo bar abc def
0 1 2.0 3.0 4
2 1 2.0 3.0 4
Мы можем попытаться обойти это, используя только столбцы, в которых нет пропущенных значений:
print(df[df.duplicated(['foo', 'def'], keep=False)])
>>>
foo bar abc def
0 1 2.0 3.0 4
1 1 NaN 3.0 4
2 1 2.0 3.0 4
4 1 2.0 NaN 4
5 5 3.0 9.0 8
6 5 NaN 9.0 8
7 5 6.0 7.0 8
Очень близко, но не совсем. Оказывается, мы упускаем важную информацию в столбце ab c, которая позволяет нам определить, что строка 7 не является дубликатом. Поэтому мы хотели бы включить его:
print(df[df.duplicated(['foo', 'def', 'abc'], keep=False)])
>>>
foo bar abc def
0 1 2.0 3.0 4
1 1 NaN 3.0 4
2 1 2.0 3.0 4
5 5 3.0 9.0 8
6 5 NaN 9.0 8
И ему удалось удалить строку 7. Однако он также удаляет строку 4. NaN считается отдельным отдельным значением, а не чем-то, что может быть равно что угодно, поэтому его присутствие в строке 4 не позволяет нам обнаружить этот дубликат.
Теперь я знаю, что мы не знаем наверняка, действительно ли строка 4 является [1, 2, 3, 4]. Насколько нам известно, это может быть что-то совсем другое, например [1, 2, 9, 4]. Но предположим, что значения 1 и 4 на самом деле являются некоторыми другими значениями, которые странно указаны c. Например, 34900 и 23893. Допустим, есть еще много столбцов, которые также точно такие же. Более того, полные повторяющиеся строки - это не просто 0 и 2, их более двухсот, а затем еще 40 строк, которые имеют те же значения во всех столбцах, кроме 'ab c', где они имеют NaN. Таким образом, для этой конкретной группы дубликатов такие совпадения крайне маловероятны, и именно поэтому мы знаем наверняка, что запись [1, 2, 3, 4] проблематична c, а эта строка 4 почти наверняка является дубликатом.
Однако, если [1, 2, 3, 4] не единственная группа дубликатов, то возможно, что некоторые другие группы имеют очень нестандартные c значения в столбцах 'foo' и 'def'. , например, 1 и 500. И так случилось, что включение столбца «ab c» в подмножество было бы чрезвычайно полезно для решения этой проблемы, потому что значения в столбце «ab c» почти всегда очень конкретны c, и позволяют практически точно определять все дубликаты. Но есть недостаток - в столбце «ab c» отсутствуют значения, поэтому, используя его, мы жертвуем обнаружением некоторых дубликатов с NaN. Некоторые из них, как мы знаем, являются дубликатами (например, вышеупомянутые 40), так что это трудная дилемма.
Что было бы лучшим способом справиться с этой ситуацией? Было бы неплохо, если бы мы могли как-то сделать NaN равными всему, а не ничему, на время обнаружения дубликатов, что решило бы эту проблему. Но я сомневаюсь, что это возможно. Могу ли я просто go группировать по группам и проверять это вручную?