Я хочу объединить два фрейма данных путем частичного совпадения строк. Мне нужно объединить два фрейма данных. Первый 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