Pandas разделяет столбец имени на имя и фамилию, если содержит один пробел

python pandas

5274 просмотра

2 ответа

80 Репутация автора

Допустим, у меня есть пандас DataFrame, содержащий имена, например:

name_df = pd.DataFrame({'name':['Jack Fine','Kim Q. Danger','Jane Smith', 'Juan de la Cruz']})

    name
0   Jack Fine
1   Kim Q. Danger
2   Jane Smith
3   Juan de la Cruz

и я хочу разбить nameстолбец на first_nameи last_nameесли в имени есть один пробел. В противном случае я хочу, чтобы полное имя было добавлено first_name.

Таким образом, окончательный DataFrame должен выглядеть так:

  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

Однако применение этой функции к моему исходному name_df приводит к пустому DataFrame, а не к заполненному именами, которые можно разделить и Nones.

Буду признателен за помощь в получении моего нынешнего подхода к работе или решений, использующих другой подход!

Автор: unpairestgood Источник Размещён: 18.07.2016 01:22

Ответы (2)


4 плюса

211821 Репутация автора

Решение

Вы можете использовать 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

РЕДАКТИРОВАТЬ

Вы можете вызвать splitс параметром, expand=Trueэто будет заполнять только там, где длина имени ровно 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
Автор: EdChum - Reinstate Monica Размещён: 18.07.2016 01:24

0 плюса

305 Репутация автора

У меня были некоторые проблемы, IndexError: list index out of rangeпотому что имена могли быть 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]
Автор: ivansabik Размещён: 08.08.2018 03:30
Вопросы из категории :
32x32