Сложная дедупликация

У меня большой фреймворк, и я хочу создать «уникальный идентификатор» для каждого отдельного человека. Соответствующий столбец - это столбец «электронная почта», но он усложняется форматированием: у каждого человека может быть несколько электронных писем. Пример кадра ниже:

Name of person ||| E-mail Address
'John Doe'     ||| '[email protected]'
'Bob Jones'    ||| '[email protected];[email protected]'
'Robert Jones' ||| '[email protected];[email protected]'
'Clara Bit'    ||| '[email protected]'
'John Doe'     ||| '[email protected];[email protected]'

Я хочу иметь поле, чтобы различать людей как личности на основе электронных писем:

Name of person ||| person ID
'John Doe'         1
'Bob Jones'        2
'Robert Jones'     2
'Clara Bit'        3
'John Doe'         4

Мой мозг как бы взрывается, пытаясь понять, как это сделать с помощью циклов for, поэтому я надеюсь, что есть более простой способ (плюс, я много повторяю df.index, что, как мне сказали, является плохим тоном и невероятно медленно, несмотря ни на что). Есть ли функция, которая могла бы что-то сделать, если бы я сделал несколько столбцов электронной почты с отдельными элементами электронной почты?

Спасибо!

Обновлено: извиняюсь за опечатку в третьей строке электронных писем, она исправлена.

в вашем текущем примере, Боб и Роберт Джонс не обмениваются электронным письмом, один из Роберта должен быть [email protected]?

wpercy 25.10.2018 18:12

Непонятно, как вы сгруппировали Bob Jones с Robert Jones, ни одно из полей в их столбце email не совпало.

Rocky Li 25.10.2018 18:13

предположительно отсутствие буквы "j" в последнем электронном письме aboy.net является опечаткой

TravisThomas 25.10.2018 18:17

Я бы использовал dict, который сопоставляет адреса электронной почты с UID. Проверка того, входит ли электронное письмо в число ключей словаря, выполняется быстро и тривиально.

TravisThomas 25.10.2018 18:51
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
4
96
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Предполагая, что в общей электронной почте есть опечатка, это проблема с несколькими шагами, которая включает библиотеки pandas и networkx, это проблема сети, и я черпал вдохновение из этих двух вопросов проблемы с сетью и проблема с разделением списка:

(1) Добавляйте электронные письма в списки
(2) Расширить столбец электронной почты (3) Создайте крайние списки пользователей с одинаковыми адресами электронной почты
(4) Создайте сеть с этим edgelist
. (5) Извлеките различные подграфы сети, которые будут представлять ваш уникальный идентификатор
. (6) Назначьте эти уникальные идентификаторы оригинальным людям.

(1) Добавляйте электронные письма в списки

import pandas as pd  
df = pd.DataFrame({'name':['John','Bob', 'Rob', 'Clara', 'John'], 'email':['[email protected]','[email protected];[email protected]','[email protected];[email protected]','[email protected]','[email protected];[email protected]']}) 
df['email_list'] = df['email'].str.split(';').tolist()

(2) Расширить столбец электронной почты

df_emails = df['email_list'].apply(pd.Series).reset_index().melt(id_vars='index',value_name='email').dropna()[['index', 'email']].set_index('index')

(3) Создавайте крайние списки пользователей с одинаковыми адресами электронной почты.

df_emails['email_id'] = df_emails.groupby('email').ngroup()
df_emails = df_emails.reset_index()
network = df_emails.merge(df_emails, on='email_id').drop(columns=['email_id', 'email_x', 'email_y'])

(4) Создайте сеть с этим списком.

import networkx as nx
G = nx.from_pandas_edgelist(network, source='index_x', target='index_y')

(5) Извлеките различные подграфы сети, которые будут представлять ваш уникальный идентификатор.

l = [list(x.nodes()) for x in nx.connected_component_subgraphs(G)]

(6) Назначьте эти уникальные идентификаторы оригинальным людям.

d = dict((k, i) for i in range(len(l)) for k in l[i])
df['unique_id'] = df.index.map(d)

Конечный результат:

    name    email   email_list  unique_id
0   John    [email protected] [[email protected]]   0
1   Bob [email protected];[email protected]   [[email protected], [email protected]]    1
2   Rob [email protected];[email protected]  [[email protected], [email protected]]   1
3   Clara   [email protected]  [[email protected]]    2
4   John    [email protected];[email protected] [[email protected], [email protected]]  3

Замечательный ответ, большое вам спасибо! Проверено, работает, теперь мне просто нужно сесть и разобраться, почему: P

Jim Eisenberg 26.10.2018 10:40

Другие вопросы по теме