Python 如果包含一个空格,请将“姓名”列拆分为“姓名”和“姓氏”

Python 如果包含一个空格,请将“姓名”列拆分为“姓名”和“姓氏”,python,pandas,Python,Pandas,假设我有一个pandas数据框,其中包含如下名称: name_df=pd.DataFrame({'name':['jackfine'、'kimq.Danger'、'janesmith'、'juandelacruz']}) 如果名称中有一个空格,我想将name列拆分为first\u name和last\u name。否则,我希望将全名插入first\u name 因此,最终的数据帧应该如下所示: first_name last_name 0 Jack Fine 1

假设我有一个pandas数据框,其中包含如下名称:

name_df=pd.DataFrame({'name':['jackfine'、'kimq.Danger'、'janesmith'、'juandelacruz']})

如果名称中有一个空格,我想将
name
列拆分为
first\u name
last\u name
。否则,我希望将全名插入
first\u name

因此,最终的数据帧应该如下所示:

  first_name     last_name
0 Jack           Fine
1 Kim Q. Danger
2 Jane           Smith
3 Juan de la Cruz
我已经尝试通过首先应用以下函数来返回可以分为名字和姓氏的名字来实现这一点:

def validate_single_space_name(name: str) -> str:
    pattern = re.compile(r'^.*( ){1}.*$')
    match_obj = re.match(pattern, name)
    if match_obj:
        return name
    else:
        return None
然而,将此函数应用于我的原始名称_df会导致一个空数据框,而不是一个由可以拆分和非的名称填充的数据框


请帮助我获得目前的工作方法,或采用不同方法的解决方案,将不胜感激

您可以使用
str.split
拆分字符串,然后使用
str.len
测试拆分的数量,并将其用作布尔掩码,以仅分配拆分最后一个组件的行:

In [33]:
df.loc[df['name'].str.split().str.len() == 2, 'last name'] = df['name'].str.split().str[-1]
df

Out[33]:
              name last name
0        Jack Fine      Fine
1    Kim Q. Danger       NaN
2       Jane Smith     Smith
3  Juan de la Cruz       NaN
编辑

您可以使用param
expand=True调用
split
,这将仅在名称长度正好为2个名称的情况下填充:

In [16]:
name_df[['first_name','last_name']] = name_df['name'].loc[name_df['name'].str.split().str.len() == 2].str.split(expand=True)
name_df

Out[16]:
              name first_name last_name
0        Jack Fine       Jack      Fine
1    Kim Q. Danger        NaN       NaN
2       Jane Smith       Jane     Smith
3  Juan de la Cruz        NaN       NaN
然后,您可以使用
fillna
替换缺少的名字:

In [17]:
name_df['first_name'].fillna(name_df['name'],inplace=True)
name_df
​
Out[17]:
              name       first_name last_name
0        Jack Fine             Jack      Fine
1    Kim Q. Danger    Kim Q. Danger       NaN
2       Jane Smith             Jane     Smith
3  Juan de la Cruz  Juan de la Cruz       NaN

我在
索引器方面遇到了一些问题:列表索引超出范围
,因为名称可能是
test
kk
和其他奇怪的用户输入。所以最后的结果是这样的:

items['fullNameSplitLength'] = items['fullName'].str.split().str.len()
items['firstName'] = items['lastName'] = ''
items.loc[
  items['fullNameSplitLength'] >= 1,
  'firstName'
] = items.loc[items['fullNameSplitLength'] >= 1]['fullName'].str.split().str[0]
items.loc[
  items['fullNameSplitLength'] >= 2,
  'lastName'
] = items.loc[items['fullNameSplitLength'] >= 2]['fullName'].str.split().str[-1]

这很接近,但并不完全正确。如果只有一个空格,我需要的名字是“杰克”,而不是“杰克好”。我正在努力解决这个问题…非常酷,谢谢!实际上,我只是让它以更详细的方式工作,因此我欣赏您的解决方案的优雅。使用您编辑的解决方案,我得到
值错误:Colunns必须与key长度相同
@Nisba抱歉,但在评论中回答问题会适得其反。您需要发布一个实际问题,其中包含数据、代码以重现df、期望的结果、您的尝试,以及任何errors@EdChum好的,我明白了。无论如何,我用这里提出的解决方案解决了我的问题
items['fullNameSplitLength'] = items['fullName'].str.split().str.len()
items['firstName'] = items['lastName'] = ''
items.loc[
  items['fullNameSplitLength'] >= 1,
  'firstName'
] = items.loc[items['fullNameSplitLength'] >= 1]['fullName'].str.split().str[0]
items.loc[
  items['fullNameSplitLength'] >= 2,
  'lastName'
] = items.loc[items['fullNameSplitLength'] >= 2]['fullName'].str.split().str[-1]