我的数据框很大,我想基本上为每个单独的人创建一个“唯一标识符”。相关的列是“电子邮件”列,但是由于格式设置而变得困难:每个人可以拥有多封电子邮件。下面的示例框架:
Name of person ||| E-mail Address
'John Doe' ||| 'john.c.doe@choo.com'
'Bob Jones' ||| 'bobbyj@aboy.net;bob.jones@omic.com'
'Robert Jones' ||| 'robert@mail.com;bobbyj@aboy.net'
'Clara Bit' ||| 'clara@mail.com'
'John Doe' ||| 'j.diddy@ack.org;jjd@ila.hun'
我希望有一个字段可以根据电子邮件将人作为个人加以区分:
Name of person ||| person ID
'John Doe' 1
'Bob Jones' 2
'Robert Jones' 2
'Clara Bit' 3
'John Doe' 4
我的大脑有点想弄清楚如何使用for循环来完成它,所以我希望有一种更简单的方法(另外,我在df.index上进行了很多迭代,我被告知是不好的格式,而且无论如何都非常慢)。如果我使用单个电子邮件元素创建了多个电子邮件列,是否可以执行某些功能?
谢谢!
编辑:很抱歉,电子邮件第三行的错字已解决。
答案 0 :(得分:3)
假设共享电子邮件上有错字,这是一个涉及熊猫和networkx库的多步骤问题,这是一个网络问题,我从这两个问题network problem和{{3}中得到了启发}:
(1)将电子邮件吐入列表中
(2)展开电子邮件列
(3)创建具有相同电子邮件的用户边缘列表
(4)使用该边缘列表创建网络
(5)提取网络中代表您唯一ID的不同子图
(6)将这些唯一的ID分配给原始人
(1)将电子邮件吐入列表
import pandas as pd
df = pd.DataFrame({'name':['John','Bob', 'Rob', 'Clara', 'John'], 'email':['john.c.doe@choo.com','bobby@aboy.net;bob.jones@omic.com','robert@mail.com;bobby@aboy.net','clara@mail.com','j.diddy@ack.org;jjd@ila.hun']})
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)提取网络中代表您唯一ID的不同子图
l = [list(x.nodes()) for x in nx.connected_component_subgraphs(G)]
(6)将那些唯一的ID分配给原始人
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 john.c.doe@choo.com [john.c.doe@choo.com] 0
1 Bob bobby@aboy.net;bob.jones@omic.com [bobby@aboy.net, bob.jones@omic.com] 1
2 Rob robert@mail.com;bobby@aboy.net [robert@mail.com, bobby@aboy.net] 1
3 Clara clara@mail.com [clara@mail.com] 2
4 John j.diddy@ack.org;jjd@ila.hun [j.diddy@ack.org, jjd@ila.hun] 3