Поиск совпадений слов одного df в другом df

Рейтинг: 0Ответов: 1Опубликовано: 13.07.2023

Есть 2 df. Один с запросами от пользователей, он состоит из колонок: id пользователя и собственно самим запросом от этого пользователя

Второй df состоит из тем которые ищут эти пользователи. В нем так же 2 колонки, одна это название темы, вторая это описание данной темы (набор слов которые ее определяют)

Как сделать так чтобы конкретный запрос пользователя - (список или текст) пробегался по WordCloud из df с темами, считал кол-во совпадений по словам и по итогу выдавал список тем с совпадениями? (и кол-во совпадающих слов)

Если совпадения найдены, то результат должен выдавать тему/ы, если их несколько(от большего кол-ва совпадений слов к меньшему). Если совпадений нет, то выдавать, что совпадений 0, а такой запрос(без совпадений) при этом должен попадать в какой-то список - чтобы понять какую тему искал пользователь но не нашел. 2 df для примера:

theme_df = pd.DataFrame(data={'Theme': ['Животные', 'Города', 'Экономика', 'Статуи', 'Погода'],
                    'WordCloud': ['Волк, медведь', 'Питер, Москва, Омск', 'питерский экономический форум', 'статуя свободы, Родина-мать', 'облачно, солнечно, погода']},
                    columns=['Theme','WordCloud'])

queries_df = pd.DataFrame(data={'id': [1, 2, 3, 4, 5],
                    'queries': ['Мерседес, автомобили', 'Питер, Москва - погода', 'питерский экономический форум', 'заяц, медведь', 'статуя']},
                    columns=['id','queries'])

Слова в запросе нужно считать по отдельности каждое слово, чем больше совпадений тем лучше, т.е. тем вероятнее попадется нужна тема

Запрос берется какой-то один (от одного пользователя), если есть совпадения, то выдается тема/ы

Ответы

▲ 1Принят

Несложный поиск можно сделать и так. Вопрос только, насколько он будет эффективен, раз каждое слово запроса нужно будет прогонять через весь датафрейм. Ну и разборка запроса тоже вызывает вопросы - считать фразу целиком или как отдельные слова:

search_df = queries_df["queries"].str.split(r"\W+").explode().values
res = {}
for x in search_df:
    r = theme_df[theme_df.loc[:, "WordCloud"].str.contains(x)]["Theme"].values
    res.setdefault(r[0] if len(r) else "no_themes",[]).append(x)

res:

{'no_themes': ['Мерседес', 'автомобили', 'заяц'], 'Города': ['Питер', 'Москва'],
 'Погода': ['погода'], 'Экономика': ['питерский', 'экономический', 'форум'],
 'Животные': ['медведь'], 'Статуи': ['статуя']}

Количество совпадений, соответственно:

n = {x:len(res[x]) for x in res.keys()}
print(n)

{'no_themes': 3, 'Города': 2, 'Погода': 1, 'Экономика': 3, 'Животные': 1, 'Статуи': 1}

Еще можно, ради интереса, через пересечение индекса:

s_df = queries_df["queries"].str.split(r"\W+").explode().reset_index().set_index("queries")
t_df = theme_df["WordCloud"].str.split(r"\W+").explode().reset_index().set_index("WordCloud")

res = t_df.join(s_df, lsuffix="t", rsuffix="s", how="inner").groupby("indext", as_index=False).count()
res["indext"] = theme_df.iloc[res["indext"], 0]

res:

      indext  indexs
0   Животные       1
1     Города       2
2  Экономика       3
3     Статуи       1
4     Погода       1

но мне как-то плохо соображается, код кажется громоздким.