当并非所有人都有中间名时,将其解析为名字,中间名和姓氏

时间:2019-12-21 15:32:55

标签: python python-3.x pandas text

我有一个看起来像这样的df:

name                           id
John McNamara                  3498
Jane Adams, M.D.               6725
Nour Abd Almohsen Jr M.D.      0197
Alex Ambrose PhD               3287
Nancy Ann Brown, MPH, PhD      9127
Kathy W.                       4389
Jack Joshua Smith White        6756

我需要将名称列分为名字,中间名,姓氏,后缀和标题。通常,我会使用类似.str.split的名称,但在这种情况下,并非每个人都有中间名,后缀或标题。此外,某些值之间用逗号分隔,而另一些则没有。有什么办法可以解决这些差异?

理想情况下,我希望输出看起来像这样:

first_name middle_name last_name    suffix title     id
John                   McNamara                      3498
Jane                   Adams               M.D.      6725
Nour       Abd         Almohsen     Jr     M.D.      0197
Alex                   Ambrose             PhD       3287
Nancy      Ann         Brown               MPH, PhD  9127
Jack       J           Smith White

edit:我知道这需要多个步骤,包括可能剥离标点符号。我发现有些事情特别棘手:

  • 如果我使用诸如pd.concat([df['id'], df['name'].str.split(' ', expand=True)], axis=1)之类的名称,则杰克·乔舒亚·史密斯·怀特(Jack Joshua Smith)这样的名字最终会分成多个“中间名”列,其中史密斯与所有其他人的姓氏在同一列。有没有办法让最后一个字符串自动进入最后一列? 我试图通过使用类似df ['last_name']。fillna(df ['middle_name'],inplace = True)的方法来解决此问题,但由于某些人有时会使用多个“中间名”,因此这是行不通的一种选择不是None的最新中间名的方法。

1 个答案:

答案 0 :(得分:1)

如果您能够获得数据框中所有可能的标题,则可以像这样解析您的姓名:

import pandas as pd

# Create the dataframe with provided sample data
names = ['John McNamara','Nour Abd Almohsen Jr M.D.','Nancy Ann Brown, MPH, PhD','MPH']
med_id = ['3498', '6725', '0197', '3287', '9127','']

df = pd.DataFrame(list(zip(names, med_id)), columns =['name', 'id']) 
names = df['name'].to_list()


# List to fill up given the dataframe content
suffix = ['M.D.', 'PhD', 'MPH']
garbages = [',']

# iterate over all the name in your list
clean_names = []
first_name = []
middle_name = []
last_name = []
title = []

# Remove suffix and junk from the names
for name in names:
    to_remove = suffix + garbages
    clean_name = name
    for element in to_remove:
        clean_name = clean_name.replace(element, '')
    clean_names.append(clean_name)

# split the clean_names into first middle and last name
for (name,original_name) in zip(clean_names,names):
    data = name.split()

    # error checking for messed up entries
    if len(data) < 2:
        first_name.append("")
        middle_name.append("")
        last_name.append("")
        title.append("")
        print("Entry : " + original_name + " is malformed")
        continue

    # Add the right firstname lastname and middle name structure
    first_name.append(data[0])
    if len(data) == 2:
        middle_name.append("")
        last_name.append(data[1])
    else:
        middle_name.append(data[1])
        last_name.append(" ".join(data[2:]))

    # Add the right title
    title.append(' ,'.join([suf for suf in suffix if suf in original_name]))

df['first_name'] = first_name
df['middle_name'] = middle_name
df['last_name'] = last_name
df['title'] = title
df = df.drop(columns = ['name','id'])

print(df)

以下是您提供的输出,包括有问题的条目: enter image description here

但是您的数据集在标点符号方面看起来很不规则