Pandas - извлекает несоответствующее слово предложения в столбце, сравнивая значение (слово) других столбцов в том же фрейме данных - PullRequest
0 голосов
/ 01 ноября 2018

Введите:

У меня есть датафрейм следующим образом

Full_Name                     Name1          Name2 
John Mathew Davidson          John           Davidson
Paul Theodre Luther           Paul           Theodre
Victor George Mary            George         Mary

Выход:

Мне нужно найти столбец Remaining_name, как показано ниже

Full_Name                     Name1       Name2       Remaining_name
John Mathew Davidson          John        Davidson       Mathew
Paul Theodre Luther           Paul        Theodre        Luther
Victor George Mary            George      Mary           Victor

Пояснение:

Мне нужно сравнить более одного значения (слова) в одном столбце со значением (предложением) другого столбца и найти несопоставимые слова, которые могут находиться в любой позиции всей строки.

Ответы [ 4 ]

0 голосов
/ 01 ноября 2018

Вы можете сделать это в одну строку с помощью:

df['Remaining_name'] = df.apply(lambda x: [i for i in x['Full_Name'].split() if all(i not in x[c] for c in df.columns[1:])], axis=1)

Это вернет ваш Remaining_name столбец как list, но эта функция будет полезна в случае, если у вас есть имена с более чем тремя подстроками, например:

                     Full_Name    Name1     Name2    Remaining_name
0         John Mathew Davidson     John  Davidson          [Mathew]
1          Paul Theodre Luther     Paul   Theodre          [Luther]
2           Victor George Mary   George      Mary          [Victor]
3  Henry Patrick John Harrison  Patrick     Henry  [John, Harrison]
0 голосов
/ 01 ноября 2018

Попробуйте это:

import numpy as np

In [835]: df
Out[835]: 
              Full_name   Name1     Name2
0  John Mathew Davidson    John  Davidson
1   Paul Theodre Luther    Paul   Theodre
2    Victor George Mary  George      Mary

ll = []

In [854]: for i, r in df.iterrows():
     ...:     big_list = r[0].split(' ')
     ...:     l1 = [r[1]]
     ...:     l2 = [r[2]]
     ...:     remaining_item = np.setdiff1d(big_list, l1+l2)[0]
     ...:     ll.append(remaining_item)
In [856]: df['Remaining_name'] = ll

In [857]: df
Out[857]: 
              Full_name   Name1     Name2 Remaining_name
0  John Mathew Davidson    John  Davidson         Mathew
1   Paul Theodre Luther    Paul   Theodre         Luther
2    Victor George Mary  George      Mary         Victor
0 голосов
/ 01 ноября 2018

Это данные, которые вы предоставили:

import pandas as pd

full_name = ['John Mathew Davidson', 'Paul Theodre Luther', 'Victor George Mary']
name_1 = ['John', 'Paul', 'George']
name_2 = ['Davidson', 'Theodre', 'Mary']

df = pd.DataFrame({'Full_Name':full_name, 'Name1':name_1, 'Name2':name_2 })

Чтобы выполнить действие над несколькими столбцами подряд, лучше всего определить функцию отдельно. Это делает код более читабельным и легче в отладке Функция будет принимать строку DataFrame в качестве ввода:

def find_missing_name(row):

    known_names = [row['Name1'], row['Name2']] ## we add known names to a list to check it later    

    full_name_list = row['Full_Name'].split(' ') ## converting the full name to the list by splitting it on spaces

    ## WARNING! this function works well only if you are sure your 'Full_Name' column items are separated by a space.

    missing_name = [x for x in full_name_list if x not in known_names] ## looping throught the full name list and comparing it to the known_names list, to only keep the missing ones.
    missing_name = ','.join(missing_name) ## in case there are more than one missing names convert them all in a string separated by comma

    return missing_name

Теперь примените функцию к существующему DataFrame:

df['missing_name'] = df.apply(find_missing_name, axis=1) ## axis=1 means 'apply to each row', where axis=0 means 'apply to each column'

Выход: enter image description here

Надеюсь, это поможет :)

0 голосов
/ 01 ноября 2018

Векторизованное решение с использованием замены,

df['Remaining_name'] = df.apply(lambda x: x['Full_Name'].replace(x['Name1'], '').replace(x['Name2'], ''), axis=1).str.strip()


    Full_Name               Name1   Name2       Remaining_name
0   John Mathew Davidson    John    Davidson    Mathew
1   Paul Theodre Luther     Paul    Theodre     Luther
2   Victor George Mary      George  Mary        Victor

Редактировать: если у вас есть много столбцов, начинающихся с имени, вы можете выбрать срез и заменить значения в Full_Name на основе шаблона регулярных выражений

df['tmp'] = df[df.columns[df.columns.str.startswith('Name')]].apply('|'.join, axis = 1)
df['Remaining_name'] = df.apply(lambda x: x.replace(x['tmp'], '', regex = True), axis = 1)['Full_Name'].str.strip()
df.drop('tmp', axis =1, inplace = True)


    Full_Name                   Name1   Name2       Remaining_name
0   John Mathew Davidson        John    Davidson    Mathew
1   Paul Theodre Luther         Paul    Theodre     Luther
2   Victor George Mary          George  Mary        Victor
3   Henry Patrick John Harrison Henry   John        Patrick Harrison
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...