我有客户数据,并想使用np.where检查他们的电子邮件是否存在于单独的df中,这将返回“匹配”或“不匹配”。
但是,客户电子邮件之一是NaN,而第二个df中的一封电子邮件是nan,因此作为匹配返回。如您所见,找到了一个匹配的先生堆栈溢出匹配项。
customers = pd.DataFrame({'firstname':['stack','Bar Bar','Foo Bar','jim','john','mary','jim'],
'lastname':['overflow','Bar','Foo Bar','ryan','con','sullivan','Ryan'],
'email':[np.nan,'Bar','Foo Bar','jim@com','john@com','mary@com','Jim@com']})
customers
firstname lastname email
0 jim bob NaN
1 Bar Bar Bar bar@com
2 Foo Bar Foo Bar foo@com
3 jim ryan jim@com
4 john con john@com
5 mary sullivan hello@com
6 jim Ryan jon@com
现在,我想检查他们的电子邮件是否在下面称为“电子邮件”的另一个数据框中:
emails = pd.DataFrame({'emails':['mary@com','bar@com','foo@com','jim@com','john@com',np.nan,'jon@com']})
emails
emails
0 mary@com
1 bar@com
2 foo@com
3 jim@com
4 john@com
5 NaN
6 jon@com
我将创建一个名为“检查”的新列,该列会将检查结果记录为“匹配”或“不匹配”
customers['check'] = np.where(customers['email'].isin(emails['emails']), 'match', 'no_match')
customers
firstname lastname email check
0 jim bob NaN match
1 Bar Bar Bar bar@com match
2 Foo Bar Foo Bar foo@com match
3 jim ryan jim@com match
4 john con john@com match
5 mary sullivan hello@com no_match
6 jim Ryan jon@com match
除了吉姆·鲍勃的唱片,一切看起来都不错。他的电子邮件是NaN,电子邮件数据框中有一个NaN。因此它作为匹配项返回。
解决这个问题的最佳方法是什么?
我当时正在考虑做一些诸如fillna()
之类的事情,并将其更改为诸如'fakeNaN'
之类的字符串,所以它没有匹配项。但是必须有更好的方法。
编辑:我刚刚尝试过:
定义了用于lambda的函数,如果客户没有电子邮件,则返回no_email。
def lam(r):
# if the email is nan, return no_email
if r == np.nan:
return 'no_email'
elif r in emails['emails']:
return 'match'
elif not r in emails['emails']:
return 'no_match'
# apply this lambda operation to the customer email row and return results to customer['check']
customers['check'] = customers.apply(lambda row: lam(row['email']), axis=1)
但是,现在所有内容都返回no_match。有一些比赛。
0 no_match
1 no_match
2 no_match
3 no_match
4 no_match
5 no_match
6 no_match
dtype: object
edit2 :我现在发现有些奇怪。
我可以检查emails['emails']
并查看其中jim@com
:
emails['emails']
0 mary@com
1 bar@com
2 foo@com
3 jim@com
4 john@com
5 NaN
6 jon@com
Name: emails, dtype: object
那为什么不起作用?
'jim@com' in emails['emails']
False
答案 0 :(得分:1)
isin
和np.select
m1=customers.email.isin(emails.emails.dropna().values)
m2=customers.email.notna()
customers['check']=np.select([m1&m2,~m1&m2],['match','no match'],default='no_email')
customers
firstname lastname email check
0 stack overflow NaN no_email
1 Bar Bar Bar Bar no match
2 Foo Bar Foo Bar Foo Bar no match
3 jim ryan jim@com match
4 john con john@com match
5 mary sullivan mary@com match
6 jim Ryan Jim@com no match
答案 1 :(得分:1)
将电子邮件另存为熊猫系列。稍微不合常规的方法。
*1
用于将布尔值转换为整数。
emails = pd.Series(['mary@com','bar@com','foo@com','jim@com','john@com',np.nan,'jon@com'])
(customers['email'].isin(emails)*1+customers['email'].isnull()*1).map({0:'No-Match',1:'Match',2:'No-Record'})
0 No-Record
1 No-Match
2 No-Match
3 Match
4 Match
5 Match
6 No-Match