我有一个看起来像这样的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


编辑:我知道这需要多个步骤,包括可能删除标点符号。我发现有些特别棘手的事情:


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

最佳答案

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

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)


这是您提供的输出,包括有问题的条目:
python - 当并非所有人都有中间名时,将其解析为名字,中间名和姓氏-LMLPHP

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

关于python - 当并非所有人都有中间名时,将其解析为名字,中间名和姓氏,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59437493/

10-12 21:59