在Python中将名称分隔到自己的列中

aelbi1ox  于 4个月前  发布在  Python
关注(0)|答案(4)|浏览(58)

我有一个数据集,我需要将名称分为first namemiddle namelast name,我遇到的问题是,在某些情况下,人们有两个姓氏/中间名或空格创建较大的名称。这是我所拥有的示例:

name 
John Smith 
Jack A Doe 
Jane Marie Jones Smith

字符串
我发现,做df[['firstname','middlename','middlename1','lastname']] = df['name'] .str.split(expand=True),然后只是结合中间名与逻辑在一起,这工程,但我有这个问题是,如果我使用的文件更新和一个像Josh Jacob Jingle Hiemer施密特的名字,那么它会抛出一个ValueError说:Columns must be same length as key.,因为我没有容纳5个名字的人。
name_parts = df['name'].str.split(expand = True)
df['first_name'] = name_parts[0]
df['last_name] = name_parts.iloc[:,1]
df['middle_name'] = name_parts.iloc[:,1:-1].apply(lammba row:" ".join(row.dropna()),axis = 1)
当我这样做的时候,我似乎只得到了姓氏。想要的输出应该是这样的。

first_name       middle_name            last_name 
  John                                    Smith
  Jack                A                   Doe
  Jane           Marie Jones              Smith
  Josh          Jacob Jingle Hiemer       Schmidt


任何帮助都将不胜感激。先谢谢你。

sq1bmfud

sq1bmfud1#

你可以试试pattern

pat = r'(?P<first_name>[^\s]+)\s+(?:(?P<middle_name>.*)?\s)?(?P<last_name>[^\s]+)'
out = df['name'].str.extract(pat).fillna('')

字符串
输出量:

>>> out
  first_name          middle_name last_name
0       John                          Smith
1       Jack                    A       Doe
2       Jane          Marie Jones     Smith
3       Josh  Jacob Jingle Hiemer   Schmidt

0qx6xfy6

0qx6xfy62#

另一种方法,没有regex:

df["first_name"] = (tmp := df["name"].str.split()).str[0]
df["middle_name"] = tmp.str[1:-1].str.join(" ")
df["last_name"] = tmp.str[-1]

print(df)

字符串
印刷品:

name first_name  middle_name last_name
0              John Smith       John                  Smith
1              Jack A Doe       Jack            A       Doe
2  Jane Marie Jones Smith       Jane  Marie Jones     Smith

kognpnkq

kognpnkq3#

我假设你最初的框架是这样初始化的:

import pandas as pd

df = pd.DataFrame({'name': ['John Smith',
                            'Jack A Doe',
                            'Jane Marie Jones Smith',
                            'Josh Jacob Jingle Hiemer Schmidt']})  # etc

字符串
其输出:

name
0                        John Smith
1                        Jack A Doe
2            Jane Marie Jones Smith
3  Josh Jacob Jingle Hiemer Schmidt


您可以遍历名称列表,并将每个名称拆分为一个部分列表(就像使用name_parts = df['name'].str.split(expand = True)一样)
然后,可以使用Python列表索引和切片将列表分隔为第一个值[0]、最后一个值[-1]和中间值[1:-1]

new_df = {'first_name': [],
          'middle_name': [],
          'last_name': []}

for name in df['name']:
    name_parts = name.split(" ")
    
    new_df['first_name'].append(name_parts[0])  # first part
    new_df['last_name'].append(name_parts[-1])  # last part
    
    middle_names = ' '.join(name_parts[1:-1])  # any parts in the middle
    new_df['middle_name'].append(middle_names)

new_df = pd.DataFrame(new_df)


其最终输出:

first_name         middle_names last_name
0       John                          Smith
1       Jack                    A       Doe
2       Jane          Marie Jones     Smith
3       Josh  Jacob Jingle Hiemer   Schmidt


如果您愿意使用print(df.to_string(index=False),可以在打印时隐藏右侧的索引

cuxqih21

cuxqih214#

你可以创建自己的函数来将名字分成first,middle和last,然后使用apply调用你的函数。

def get_name(x):
    data = x['name'].split()
    if len(data) == 1:
        return x, '', ''
    if len(data) == 2:
        return data[0], '', data[1]
    return data[0], ' '.join(data[1:-1]), data[-1]

df[['first_name', 'middle_name', 'last_name']] = df.apply(get_name, axis=1, result_type='expand')

字符串
输出

name first_name          middle_name last_name
0                        John Smith       John                          Smith
1                        Jack A Doe       Jack                    A       Doe
2            Jane Marie Jones Smith       Jane          Marie Jones     Smith
3  Josh Jacob Jingle Hiemer Schmidt       Josh  Jacob Jingle Hiemer   Schmidt

相关问题