Я хочу объединить два фрейма данных путем частичного совпадения строк. Мне нужно объединить два фрейма данных. Первый df1 состоит из 130 000 строк, например:
id text xc1 xc2
1 adidas men shoes 52465 220
2 vakko men suits 49220 224
3 burberry men shirt 78248 289
4 prada women shoes 45780 789
5 lcwaikiki men sunglasses 34788 745
а второй df2 состоит из 8000 строк, например:
id keyword abc1 abc2
1 men shoes 1000 11
2 men suits 2000 12
3 men shirt 3000 13
4 women socks 4000 14
5 men sunglasses 5000 15
После соответствия между ключевым словом и текстом результат должен выглядеть следующим образом:
id text xc1 xc2 keyword abc1 abc2
1 adidas men shoes 52465 220 men shoes 1000 11
2 vakko men suits 49220 224 men suits 2000 12
3 burberry men shirt 78248 289 men shirt 3000 13
4 lcwaikiki men sunglasses 34788 745 men sunglasses 5000 15
Возможно ли, что частичное совпадение строки находится в середине текста в df1? например vakko men suits blue? — person muratmert41 schedule 23.05.2021
@SeaBean Да. Когда я исследую набор данных, есть такие примеры. — person muratmert41 schedule 23.05.2021
Идентификаторы в том же порядке? — person muratmert41 schedule 23.05.2021
@AnuragDabas, к сожалению, нет. номера строк в обоих фреймах данных различаются — person muratmert41 schedule 23.05.2021
stackoverflow.com/a/60908516/14066512 — person muratmert41 schedule 23.05.2021
Еще одна сложность: men suits в df2 не должен совпадать с abc women suits в df1, верно? — person muratmert41 schedule 23.05.2021
@SeaBean, да, я бы не хотел, чтобы это совпадало. — person muratmert41 schedule 24.05.2021
В таком случае вы не можете использовать большинство похожих ответов в StackOverflows, которые используют простой тест подстроки, например stringA in stringB. Такой вид теста завершится неудачно с ложным совпадением men suits в keyword с women suits в text, поскольку он возвращает True для теста 'men suits' in 'women suits'. Мы должны использовать регулярное выражение с учетом границы слова, чтобы избежать ложного совпадения. — person muratmert41 schedule 24.05.2021
Давайте подойдем к перекрестному соединению двух фреймов данных, а затем отфильтруем их, сопоставив строку с подстрокой, как показано ниже:
Если ваша версия Pandas старше 1.2.0 (выпущена в декабре 2020 г.) и не поддерживает слияние с
how='cross', вы можете заменить оператор слияния на:После перекрестного соединения мы создали логическую маску для фильтрации случаев, когда
keywordнаходится в пределахtext, используяre.searchв.apply().Мы должны использовать
re.searchвместо простого теста подстроки Python, такого какstringA in stringB, который можно найти в большинстве похожих ответов в StackOverflow. Такой тест завершится неудачно с ложным совпадением'men suits'вkeywordс'women suits'вtext, поскольку он возвращаетTrueдля теста'men suits' in 'women suits'.Мы используем регулярное выражение с парой метасимволов границы слова
\bвокругkeyword(шаблон регулярного выражения:rf"\b{x['keyword']}\b"), чтобы гарантировать соответствие только для совпадения всего слова дляtextвdf1, т.е.men suitsвdf2не будет совпадать сwomen suitsвdf1, поскольку словоwomenне имеет границы между буквамиwoиmen.Результат:
Здесь столбцы
id_xиid_y— это исходныйidстолбец вdf1иdf2соответственно. Как видно из комментария, это просто номера строк фреймов данных, которые могут вас не беспокоить. Затем мы можем удалить эти 2 столбца и сбросить индекс, чтобы очистить макет:Окончательный результат
Спасибо за твой ответ. Я получаю следующее сообщение об ошибке:
TypeError: expected string or bytes-like objectМожет ли какое-то значение быть целым числом? — person muratmert41; 24.05.2021@ muratmert41 В таком случае сначала преобразуйте
x['text']в строку, используяstr(x['text']). Вы можете обратиться к моим отредактированным кодам выше. — person muratmert41; 24.05.2021@ muratmert41 Если я могу еще чем-нибудь помочь, дайте мне знать!
— person muratmert41; 25.05.2021
твои ответы действительно мне очень помогают. Я больше не получаю сообщение об ошибке. но есть некоторые мелкие проблемы, которые мешают мне получить правильный результат. Я над ними работаю. — person muratmert41; 25.05.2021
@ muratmert41 Посмотрим, могу ли я помочь вам, если это связано с вашим вопросом здесь. Если нет, надеюсь, вы скоро решите эту проблему! В любом случае, не забудьте принять решение и проголосовать за него! Удачи! — person muratmert41; 25.05.2021
Мне жаль, что я забыл об этом. еще раз спасибо. — person muratmert41; 25.05.2021
@ muratmert41 Добро пожаловать! Удачи в скорейшем решении ваших мелких проблем! — person muratmert41; 25.05.2021
Давайте начнем с того, что отсортируем ключевые слова в порядке убывания длины, чтобы женские костюмы соответствовали мужской одежде.
Теперь определите функцию сопоставления; каждое
textзначение изdf1будет передано какsдля поиска подходящего ключевого слова:Теперь мы можем извлечь ключевое слово из каждого
textв df1 и добавить его в новый столбец:Теперь у нас есть все, что нужно для стандартного слияния:
Спасибо за твой ответ. Я предполагаю, что некоторые значения содержат значения типа int. например, например: обод велосипеда 16 дюймов. поэтому я получаю такую ошибку:
TypeError: argument of type 'int' is not iterable— person muratmert41; 24.05.2021