使用分隔符分隔数据框中列中的字符串,并将子字符串添加到单独的列中
Separate strings in columns in a dataframe with delimiter and adding sub-strings in to separate columns
原来我的问题是:
我有数据框,例如:
df = pd.DataFrame({
"EmailAdds": ["pamelasilvera@gmail.com"],
"Subject": ["Report submission", "Meeting update"]
})
我想根据“@”将 "EmailAdds"
列中的电子邮件 ID 分开,并且必须添加具有根电子邮件 ID 和域名的列。最终的数据框应该是这样的:
df = pd.DataFrame({
"EmailAdds": ["pamelasilvera@gmail.com"],
"Subject": ["Report submission", "Meeting update"]
})
后来才知道,"EmailAdds"
这一列可以在一行数据中有多封邮件,用“;”分隔。实际上我的数据框是这样的:
df = pd.DataFrame({
"EmailAdds": ["pamelasilvera@gmail.com; adarandall@gmail.com; larryjacob@orange.com", "indiejesse.d@gmail.com"],
"Subject": ["Report submission", "Meeting update"]
})
我真正想做的是:
我想查看 "EmailAdds"
的每个元素,首先使用“;”分隔电子邮件然后使用 @ 将每个电子邮件地址分隔成子字符串,然后再添加 2 列,第一个 "EmailAdd_roots"
包含该行电子邮件地址的子字符串,比方说 "pamelasilvera adarandall larryjacob" 和第二个 "EmailAdd_domains"
包含不带“的唯一域名.com" 让我们 "gmail orange".
生成的数据框应完全如下所示:
df = pd.DataFrame({
"EmailAdds": ["pamelasilvera@gmail.com; adarandall@gmail.com; larryjacob@orange.com", "indiejesse.d@gmail.com"],
"Subject": ["Report submission", "Meeting update"],
"EmailAdds_roots": ["pamelasilvera adarandall larryjacob", "indiejesse"],
"EmailAdds_domains":["gmail orange", "gmail"]
})
我们 join
和 str.split
df=df.join(df.EmailAdd.str.split('@',expand=True))
Out[138]:
EmailAdd Subject 0 1
0 pamelasilvera@gmail.com Report submission pamelasilvera gmail.com
1 indiejesse.d@gmail.com Meeting update indiejesse.d gmail.com
我们还可以将 str.extract
与命名的正则表达式组一起使用:
df.join(df.EmailAdd.str.extract('^(?P<Email>[^@]+)@(?P<Domain>.+)'))
输出:
EmailAdd Subject Email Domain
0 pamelasilvera@gmail.com Report submission pamelasilvera gmail.com
1 indiejesse.d@gmail.com Meeting update indiejesse.d gmail.com
这里满满的:
emails = df['EmailAdds'].str.split(';').explode()
df = df.join(
emails.str.split('@', expand=True) \
.fillna('') \
.groupby(level=0) \
.agg(
{ 0: ' '.join,
1: lambda x: ' '.join(set(x))}
).rename(columns=['EmailAdds_roots', 'EmailAdds_domains'].__getitem__)
)
结果:
EmailAdds Subject \
0 pamelasilvera@gmail.com; adarandall@gmail.com;... Report submission
1 indiejesse.d@gmail.com Meeting update
EmailAdds_roots EmailAdds_domains
0 pamelasilvera adarandall larryjacob gmail.com orange.com
1 indiejesse.d gmail.com
另一个更易读的版本是:
emails = df['EmailAdds'].str.split(';').explode() \
.str.split('@', expand=True).fillna('') \
.groupby(level=0)
df['EmailAdds_roots'] = emails[0].agg(list).str.join(' ')
df['EmailAdds_domains'] = emails[1].unique().str.join(' ')
原来我的问题是:
我有数据框,例如:
df = pd.DataFrame({
"EmailAdds": ["pamelasilvera@gmail.com"],
"Subject": ["Report submission", "Meeting update"]
})
我想根据“@”将 "EmailAdds"
列中的电子邮件 ID 分开,并且必须添加具有根电子邮件 ID 和域名的列。最终的数据框应该是这样的:
df = pd.DataFrame({
"EmailAdds": ["pamelasilvera@gmail.com"],
"Subject": ["Report submission", "Meeting update"]
})
后来才知道,"EmailAdds"
这一列可以在一行数据中有多封邮件,用“;”分隔。实际上我的数据框是这样的:
df = pd.DataFrame({
"EmailAdds": ["pamelasilvera@gmail.com; adarandall@gmail.com; larryjacob@orange.com", "indiejesse.d@gmail.com"],
"Subject": ["Report submission", "Meeting update"]
})
我真正想做的是:
我想查看 "EmailAdds"
的每个元素,首先使用“;”分隔电子邮件然后使用 @ 将每个电子邮件地址分隔成子字符串,然后再添加 2 列,第一个 "EmailAdd_roots"
包含该行电子邮件地址的子字符串,比方说 "pamelasilvera adarandall larryjacob" 和第二个 "EmailAdd_domains"
包含不带“的唯一域名.com" 让我们 "gmail orange".
生成的数据框应完全如下所示:
df = pd.DataFrame({
"EmailAdds": ["pamelasilvera@gmail.com; adarandall@gmail.com; larryjacob@orange.com", "indiejesse.d@gmail.com"],
"Subject": ["Report submission", "Meeting update"],
"EmailAdds_roots": ["pamelasilvera adarandall larryjacob", "indiejesse"],
"EmailAdds_domains":["gmail orange", "gmail"]
})
我们 join
和 str.split
df=df.join(df.EmailAdd.str.split('@',expand=True))
Out[138]:
EmailAdd Subject 0 1
0 pamelasilvera@gmail.com Report submission pamelasilvera gmail.com
1 indiejesse.d@gmail.com Meeting update indiejesse.d gmail.com
我们还可以将 str.extract
与命名的正则表达式组一起使用:
df.join(df.EmailAdd.str.extract('^(?P<Email>[^@]+)@(?P<Domain>.+)'))
输出:
EmailAdd Subject Email Domain
0 pamelasilvera@gmail.com Report submission pamelasilvera gmail.com
1 indiejesse.d@gmail.com Meeting update indiejesse.d gmail.com
这里满满的:
emails = df['EmailAdds'].str.split(';').explode()
df = df.join(
emails.str.split('@', expand=True) \
.fillna('') \
.groupby(level=0) \
.agg(
{ 0: ' '.join,
1: lambda x: ' '.join(set(x))}
).rename(columns=['EmailAdds_roots', 'EmailAdds_domains'].__getitem__)
)
结果:
EmailAdds Subject \
0 pamelasilvera@gmail.com; adarandall@gmail.com;... Report submission
1 indiejesse.d@gmail.com Meeting update
EmailAdds_roots EmailAdds_domains
0 pamelasilvera adarandall larryjacob gmail.com orange.com
1 indiejesse.d gmail.com
另一个更易读的版本是:
emails = df['EmailAdds'].str.split(';').explode() \
.str.split('@', expand=True).fillna('') \
.groupby(level=0)
df['EmailAdds_roots'] = emails[0].agg(list).str.join(' ')
df['EmailAdds_domains'] = emails[1].unique().str.join(' ')