使用分隔符分隔数据框中列中的字符串,并将子字符串添加到单独的列中

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"]
            })

我们 joinstr.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(' ')