Python. Заменить подстроку вначале текстовой строки в датафрейме на основании другого датафрейма
Есть два датафрейма:
reference = [['поселок ', 'поселок'], ['посёлок ', 'поселок'], ['п ', 'поселок'], ['п. ', 'поселок']]
reference = pd.DataFrame(reference, columns = ['dirty', 'clean'])
data = [['посёлок Подгорный'], ['посeлок Глинка'], ['п. Новокамышенка']]
data = pd.DataFrame(data, columns = ['setll'])
Хочу сделать проверку: если setll из data начинается на одно из значений dirty из reference, то из setll извлечь dirty. Пробую так:
def extract_settl_type(df_column):
for dirty, clean in reference.itertuples(index=False):
if df_column.startswith(dirty):
setll_norm = df_column.replace(dirty, '')
setll_type_norm = clean
return setll_norm, setll_type_norm
else:
return None
data['setll_norm'] = data['setll'].apply(extract_settl_type)
Но возвращается None: | |setll | setll_norm | | --------- |--------- | -------------- | |0 |посёлок Подгорный |None| |1 |посeлок Глинка |None| |2 |п. Новокамышенка |None|
Хотя если пробовать на отдельном значении:
strr = 'посёлок Подгорный'
for dirty, clean in reference.itertuples(index=False):
if strr.startswith(dirty):
print(dirty)
То возвращается "посёлок ", то есть не None. Камрады, что я упускаю в функции extract_settl_type? :с
Ответы (1 шт):
Автор решения: Максим Науменко
→ Ссылка
Немного оптимизировал и поменял нейминги. Если я правилно понял задачу, то вот мой вариант:
import pandas as pd
references = pd.DataFrame(
columns=['dirty', 'clean'],
data=[['посёлок', 'поселок'],
['п', 'поселок'],
['п.', 'поселок']]
)
data = pd.DataFrame(
columns=['raw_locality'],
data=[['посёлок Подгорный'],
['посeлок Глинка'],
['п. Новокамышенка']]
)
def locality_type_replacer(raw_str: str) -> str:
"""
Replace locality type
"""
split_string: list = raw_str.split(" ")
raw_type = split_string[0] if len(split_string) > 1 else None
# Check raw_type exist, raw_type in references, string starts of raw_type
if not any((
raw_type,
raw_type in tuple(references['dirty']),
raw_str.startswith(raw_type)
)):
return raw_str
# Get index for mapping
index = references.dirty[references.dirty == 'п'].index
# Get value for rename
mapped_value = references.clean[index].item()
# Replace locality type
split_string[0] = mapped_value
return ' '.join(split_string)
data['locality'] = data['raw_locality'].apply(locality_type_replacer)
data
