对返回“None”的两列应用操作

2024-05-14 23:11:41 发布

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

我正在尝试将电子邮件清理功能应用于一个列,并将结果记录在单独的列中。你知道吗

我不完全确定如何将函数应用于带有.apply()的两列,但下面是我尝试过的:

首先设置dataframe和常见电子邮件错误字典:

import pandas as pd

df = pd.DataFrame({'emails':['jim@gmailcom','bob@gmail.com','mary@gmaicom','bobby@gmail.com'],
                   'result':['','','','']})

df

    emails          result
0   jim@gmailcom    
1   bob@gmail.com   
2   mary@gmaicom    
3   bobby@gmail.com 

# common mistakes:

correct_domain = {'gmailcom': 'gmail.com',
 'gmaicom': 'gmail.com',
 'gmaillom': 'gmail.com',
 'gmalcom': 'gmail.com'}

现在我想浏览电子邮件,并用正确的域替换错误的域。例如gmailcom->;gmail.com你知道吗

def clean_emails(x):

    # for each domain(key) in this dict ( e.g. 'gmailcom':'gmail.com')
    for mistake in correct_domain:  

        # if incorrect domain ('gmailcom') is in the email we're checking
        if mistake  in x['emails']:

            # replace it with the dict value which is the correctly formatted domain ('gmail.com')
            x['emails'] = x['emails'].replace(mistake ,correct_domain[mistake ])

            # record result
            x['result'] = 'email cleaned'

        else:
            x['result'] = 'no cleaning needed'

当我应用这个函数时,我没有得到任何结果:

df.apply(clean_emails,axis=1)

0    None
1    None
2    None
3    None
dtype: object

我尝试在混合中使用return,但无法为单独的列计算出两个单独的返回值。你知道吗

我想要的结果是,邮件已被清理,结果记录到result

    emails          result
0   jim@gmail.com    'email cleaned'    
1   bob@gmail.com   'no cleaning needed'    
2   mary@gmail.com    'email cleaned'   
3   bobby@gmail.com 'no cleaning needed'

编辑:我以为在函数末尾添加return x会返回新编辑的行,但是电子邮件没有被清除。你知道吗

    emails  result
0   jim@gmail.com   email cleaned
1   bob@gmail.com   no cleaning needed
2   mary@gmaicom    no cleaning needed
3   bobby@gmail.com no cleaning needed

Tags: nocom电子邮件emaildomainresultgmailbob
3条回答

我一直在想,你已经有很多解决方案了。按照你的逻辑,我们可以做到:


    df = pd.DataFrame({'emails':['jim@gmailcom','bob@gmail.com','mary@gmaicom','bobby@gmail.com']})

    regexExp = [r'gmailcom$', r'gmaicom$', r'gmaillom', r'gmalcom']

    df2 = df.replace(regex=regexExp, value='gmail.com')

    result = []
    for dfLines, df2Lines in zip(df.itertuples(),df2.itertuples()):
        if df2Lines.emails != dfLines.emails:
            result.append('email cleaned')
        else:
            result.append('no cleaning needed')

    df2['result'] = result

    print(df2)

为什么不是两行:

df['result'] = df['emails'].str.contains('|'.join(correct_domain.keys()).map({0:'email cleaned', 1:'no cleaning needed'})
df['emails'] = df['emails'].str.replace('|'.join(correct_domain.keys()),list(correct_domain.values())[0])

现在:

print(df)

将是:

            emails              result
0    jim@gmail.com       email cleaned
1    bob@gmail.com  no cleaning needed
2   mary@gmail.com       email cleaned
3  bobby@gmail.com  no cleaning needed

如有必要,使用^{}进行检查,使用^{}进行按条件列的清理,然后使用^{}和callback进行仅由字典替换的必要行:

pat = '|'.join(correct_domain.keys())
m = df['emails'].str.contains(pat, na=False)
df['result'] = np.where(m, 'email cleaned', 'no cleaning needed')
df.loc[m, 'emails'] = (df.loc[m, 'emails']
                         .str.replace(pat, lambda x: correct_domain[x.group()], regex=True))

print (df)
            emails              result
0    jim@gmail.com       email cleaned
1    bob@gmail.com  no cleaning needed
2   mary@gmail.com       email cleaned
3  bobby@gmail.com  no cleaning needed

相关问题 更多 >

    热门问题