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

2024-10-03 02:42:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我最初的问题是:

我有dataframe,例如:

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"的每个元素,首先使用“;”分隔电子邮件然后使用@将每个电子邮件地址分隔成子字符串,然后再添加两列,第一列"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"]
            })

Tags: 数据reportcomsubmissiondataframedf电子邮件update
3条回答

这里有一个满嘴的:

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(' ')

我们还可以将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

我们用str.splitjoin

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

相关问题 更多 >