在Python中解析姓名中的姓氏

3
尝试确定一个姓氏。
names = ["John Smith", "D.J. Richies III","AJ Hardie Jr.", "Shelia Jackson-Lee", "Bob O'Donnell"]

期望的输出

last_names = ['Smith', 'Richies','Hardie','Lee', 'ODonnell' ]

我希望有一个现有的库或一套代码可以轻松地处理一些较为罕见/奇特的情况。

谢谢你的帮助!


2
向他人推荐库通常不被视为适当的问题,不能在SO上提问。你尝试过什么?看起来你只需要在str.split()之后取第二个单词并删除标点符号,这可以使用标准字符串函数轻松完成。 - AChampion
还有,如果你有中间名呢?或者姓氏是两个单词而没有连字符呢? - Adam Michael Wood
实际上,在这里使用库是一个不错的选择。处理应用程序中的名称比大多数人意识到的要困难,我不会感到惊讶,如果有人已经将类似于此的东西组合成了一个库。 - Adam Michael Wood
我认为这些名字是从网站上抓取的,因此没有中间名。虽然我没有每个例子,但在查看了几百个之后,似乎没有中间名,这就是为什么我认为AChampion的解决方案可能有效的原因。 - nonegiven72
顺便提一下 - 您的示例输出从 O'Donnell 中删除了撇号。这不是一个好习惯。 - Adam Michael Wood
显示剩余3条评论
3个回答

10

姓名处理很难

简单的字符串操作最终会失败。在后缀(IIIJr.)中您会开始意识到这一点,但对于像 de la Paz 这样的复合姓呢?

您需要:Python 人名解析器

>>> from nameparser import HumanName
>>> name = HumanName("Dr. Juan Q. Xavier de la Vega III")
>>> name.title
'Dr.'
>>> name["title"]
'Dr.'
>>> name.first
'Juan'
>>> name.middle
'Q. Xavier'
>>> name.last
'de la Vega'
>>> name.suffix
'III'

1
你可以试试这个:

names = ["John Smith", "D.J. Richies III","AJ Hardie Jr.", "Shelia Jackson-Lee", "Bob O'Donnell"]

suffixes = ["II", "Jr.", "III", "Sr."]

last_names = []

for i in names:
    new_name = i.split()
    if len(new_name) == 2 and "-" in new_name[1]:
         last_names.append(new_name[1].split("-")[1])

    elif len(new_name) == 2:
          last_names.append(new_name[1])

    else:
        if new_name[-1] in suffixes:
           last_names.append(new_name[1])

print(last_names)

输出将包含姓氏:
['Smith', 'Richies', 'Hardie', 'Lee', "O'Donnell"]

这可以与后缀列表结合使用以进行剥离。 - Adam Michael Wood

1
你可以使用 nameparser 包。更多示例请查看链接
from nameparser import HumanName
import pandas as pd

df = pd.DataFrame({'Name': ["John Smith", "D.J. Richies III","AJ Hardie Jr.", "Shelia Jackson-Lee", "Bob O'Donnell"]})

df["title"] = df["Name"].apply(lambda x: HumanName(x).title)
df["first"] = df["Name"].apply(lambda x: HumanName(x).first)
df["middle"] = df["Name"].apply(lambda x: HumanName(x).middle)
df["last"] = df["Name"].apply(lambda x: HumanName(x).last)
df["suffix"] = df["Name"].apply(lambda x: HumanName(x).suffix)
df["nickname"] = df["Name"].apply(lambda x: HumanName(x).nickname)
df 

而输出结果是:

                 Name title   first middle         last suffix nickname
0          John Smith          John               Smith                
1    D.J. Richies III          D.J.             Richies    III         
2       AJ Hardie Jr.            AJ              Hardie    Jr.         
3  Shelia Jackson-Lee        Shelia         Jackson-Lee                
4       Bob O'Donnell           Bob           O'Donnell          

如果你只想要姓氏:

df['last']

你会得到:

0          Smith
1        Richies
2         Hardie
3    Jackson-Lee
4      O'Donnell
Name: last, dtype: object

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接