Как разделить строку во фрейме данных на основе количества пробелов

#python #pandas

Вопрос:

У меня есть поле в фрейме данных со следующими именами

 Joseph Sam Smith
Angela Savage
James Taylor
William Smith Jr
 

Я хочу разделить его на четыре столбца: имя, отчество, фамилия, суффикс. Для этого набора данных, вероятно, нормально (хотя и не идеально) предполагать, что единственным возможным суффиксом является Jr.

У меня есть разделение, предполагающее только первое и последнее, но потом я понял, что мне нужно больше, чем это.

df[['first_name','last_name']] = df['name'].str.split(" ", 1, expand=True)

Заранее спасибо!

Ответ №1:

Не векторизованный подход, но он выполняет свою работу. Существует предположение, что у каждого человека есть минимум имени и фамилии, т. е. нет «Шер» или «Принц-младший».

установка

 data = pd.Series([
    "Joseph Sam Smith",
    "Angela Savage",
    "James Taylor",
    "William Smith Jr",
])

suffixes = ["Jr", "III"]
 

решение

 def decipher(name):
    l = [None]*4  # placeholder list
    tokens = name.split()
    l[0] = tokens.pop(0)  # first name
    if tokens[-1] in suffixes:  
        l[-1] = tokens.pop()  # add suffix to end of list
    l[2] = tokens.pop()  # last element of tokens must be last name
    if len(tokens) > 0:  # if there any elements left they are a middle name
        l[1] = tokens.pop()
    return pd.Series(l)

result = data.apply(decipher)
 

result является

          0     1       2     3
0   Joseph   Sam   Smith  None
1   Angela  None  Savage  None
2    James  None  Taylor  None
3  William  None   Smith    Jr
 

Ответ №2:

 name = "Joseph Sam Smith"
df =[["first_name","middle_name","last_name","suffix"]]
nameLis = name.split(" ")
if(len(nameLis)==3):
    nameLis.append("")
elif(len(nameLis)==2):
    nameLis.insert(1,"")
    nameLis.insert(3,"")

df.append(nameLis)
 

Ответ №3:

 >>> import pandas as pd
>>> x = pd.Series(["Joseph Sam Smith","Angela Savage", "James Taylor", "William Smith Jr"])
>>> x

0    Joseph Sam Smith
1       Angela Savage
2        James Taylor
3    William Smith Jr
dtype: object
 
 >>> d = x.str.split(expand=True)
>>> d['suffix'] = None
>>> d.columns = ['FirstName', 'MiddleName', 'LastName', 'suffix']
>>> matched = d.loc[d.LastName.eq("Jr")]
>>> d.iloc[matched.index, 3] = d.iloc[matched.index, 2].to_list()
>>> d.iloc[matched.index, 2] = None
>>> d


    FirstName   MiddleName  LastName    suffix
0   Joseph      Sam         Smith       None
1   Angela      Savage      None        None
2   James       Taylor      None        None
3   William     Smith       None        Jr