У нас есть следующие два фрейма данных
temp = pd.DataFrame(np.array([['I am feeling very well',1],['It is hard to believe this happened',0],
['What is love?',1], ['No new friends',0],
['I love this show',1],['Amazing day today',1]]),
columns = ['message','sentiment'])
temp_truncated = pd.DataFrame(np.array([['I am feeling very',1],['It is hard to believe',1],
['What is',1], ['Amazing day',1]]),
columns = ['message','cutoff'])
Моя идея состоит в том, чтобы создать третий DataFrame, который будет представлять внутреннее соединение между temp и temp_truncated, находя совпадения в temp, которые начинаются с/содержат строки в temp_truncated
Желаемый результат:
message sentiment cutoff
0 I am feeling very well 1 1
1 It is hard to believe this happened 0 1
2 What is love 1 1
3 Amazing day today 1 1
@mozway Я только что понял, что использовал другой образец. Зафиксированный. Глядя в решение.






Вы можете использовать:
import re
pattern = '|'.join(map(re.escape, temp_truncated['message']))
key = temp['message'].str.extract(f'({pattern})', expand=False)
out = (temp
.merge(temp_truncated.rename(columns = {'message': 'sub'}),
left_on=key, right_on='sub')
.drop(columns='sub')
)
Вывод:
message sentiment cutoff
0 I am feeling very well 1 1
1 It is hard to believe this happened 0 1
2 What is love? 1 1
3 Amazing day today 1 1
Вот подход, использующий rapidfuzz с pandas.merge:
#pip install rapidfuzz
from rapidfuzz import process
out = (
temp_truncated
.assign(message_adapted = (temp_truncated['message']
.map(lambda x: process.extractOne(x, temp['message']))).str[0])
.merge(temp, left_on = "message_adapted", right_on = "message", how = "left", suffixes=("_", ""))
.drop(columns=["message_adapted", "message_"])
.loc[:, temp.columns.tolist() + ["cutoff"]]
)
print(out)
message sentiment cutoff
0 I am feeling very well 1 1
1 It is hard to believe this happened 0 1
2 What is love? 1 1
3 Amazing day today 1 1
Обратите внимание, что нечеткое сопоставление и сопоставление подстрок — это не одно и то же. Если вы замените Amazing Day на Amazing Job в temp_truncated, это все равно будет соответствовать (вероятно, не должно)
Для меня не было никакой разницы, особенно когда я получил точный ожидаемый результат от OP. Я удалю свой ответ, большое спасибо, mozway;)
Вам не нужно удалять, это все равно приятно, но важно, чтобы разница была понятна ;)
@abokey нет, пожалуйста, продолжайте отвечать, так как комментарий о том, чем нечеткое сопоставление отличается от фактического сопоставления, важен и должен оставаться здесь для дальнейшего использования.
Вы можете использовать str.startswith или другие функции str., такие как str.contains, в приложении для получения кадра данных совпадений:
matches = temp_truncated.message.apply(
lambda x: temp[temp.message.str.startswith(x)]['sentiment']
).dropna(how='all')
Этот фрейм данных matches содержит строки temp_truncated, которые совпадают с одной из строк в temp. Эти temp строки являются столбцами matches фрейма данных. Значения — это значения тональности этих temp строк.
При этом вы можете отфильтровать фрейм данных temp только совпавшими строками, а затем обогатить его соответствующим значением отсечки из temp_truncated:
df = temp.iloc[matches.columns]
df.index = matches.index
df = df.merge(temp_truncated['cutoff'], left_index=True, right_index=True)
Результат соответствует желаемому результату:
message sentiment cutoff
0 I am feeling very well 1 1
1 It is hard to believe this happened 0 1
2 What is love? 1 1
3 Amazing day today 1 1
Ваш вывод не полностью соответствует предоставленным данным;)