Как избежать NaN в np.where между двумя кадрами данных? - PullRequest
0 голосов
/ 08 июля 2019

У меня есть данные о клиентах, и я хочу проверить, присутствуют ли их электронные письма в отдельном df, используя np.where, который возвращает 'match' или 'no match'.

Однако одно из электронных писем клиентаNaN, и одно из электронных писем во втором df - это nan, так что это возвращается.Как видите, найдено совпадение для переполнения стека Mr.

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

Я создам новый столбец с именем «check», в котором будут записыватьсярезультат проверки как «совпадение» или «отсутствие совпадения»


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' или что-то подобное, так что это не так.придумать спичку.Но должен быть лучший способ.

edit: Я только что попробовал это:

Определил функцию для использования с 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

Ответы [ 2 ]

1 голос
/ 08 июля 2019

Сохраненные письма в виде серий панд.Слегка неортодоксальный подход.

*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

1 голос
/ 08 июля 2019

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...