Определение функции для фильтрации фрейма данных с помощью другого фрейма данных

#python #pandas #dataframe

#python #pandas #фрейм данных

Вопрос:

У меня есть два фрейма данных: bmg и etext.

 bmg = pd.DataFrame({''product_title':['%macroeconomics 101','Physics','Calculus'], 
                'author':['Abel', 'Jenkins', 'Williams'], 
                'isbn13':['1238404589228', '1238404589235', '123840458432']})
bmg


etext = pd.DataFrame({'Title':['Macroeconomics','History','Anatomy'], 
                'Author':['Abel', 'Jenkins', 'Franklin']})

etext

  

Я хочу отфильтровать набор bmg так, чтобы он включал только совпадающие значения в etext dataframe (т. Е. Имел того же автора и название, что и в etext dataframe). Вот проблема: «product_title» в наборе bmg иногда содержит дополнительные символы, поэтому это не будет прямым совпадением. Я бы хотел, чтобы это был str.contains .

Если я сделаю что-то вроде этого:

 find = 'Macroeconomics'
test = df[df['product_title'].str.contains(find, case=False, na=False)]
test
  

Фильтр работает, но, конечно, я отфильтровываю другие строки в etext, которые я хочу. Мне нужно запустить оба столбца по всему фрейму данных etext.

Ожидаемый результат для bmg:

 pd.DataFrame({''product_title':['%macroeconomics 101], 
                'author':['Abel'], 
                'isbn13':['1238404589228']})
  

Спасибо!

Комментарии:

1. Не могли бы вы опубликовать минимальный (но значимый) рабочий пример? Ввод и ожидаемый результат.

2. Привет, Риккардо — Спасибо за ваш ответ. Я добавил скриншоты фреймов данных. Мой ожидаемый результат — это просто отфильтрованный фрейм данных bmg, который содержит все str.contains для столбцов etext. Так, например, я бы хотел, чтобы он фильтровал все строки, в которых «Abel» в качестве автора и «Macroeconomics» в «product_title». Даже если в «product_title» указано: «%Макроэкономика 101»

3. Пожалуйста, опубликуйте код, который нам нужен для создания этих фреймов данных. Кроме того, каков желаемый результат? Это самая важная часть. Попробуйте создать два входных фрейма данных и один выходной и опубликовать их здесь, чтобы мы могли проверить наши решения

4. Еще раз привет — я внес изменения, которые, я надеюсь, будут полезны. Большое вам спасибо!

Ответ №1:

Вы могли бы попробовать просто объединить фреймы данных и удалить строки, которые не соответствуют вашему правилу:

 df = pd.merge(etext, bmg, left_on='Author', right_on='author')

df = df[df.apply(lambda x: x['Title'] in x['product_title'], axis=1)]
  

Затем вы можете преобразовать заголовок в индекс, если все они разные

 df = df.set_index('Title')
df.loc['Macroeconomics']
  

Комментарии:

1. Спасибо за ваш ответ. Проблема в том, что имена авторов и названия не всегда совпадают напрямую. Если у etext есть «Микроэкономика», а у bmg есть «% Microeconomics», вышеупомянутое может не сработать.

2. Вы сказали, что будут отличаться только заголовки. Это выше работает именно для того случая, который вы только что указали, если etext имеет «Микроэкономику», а bmg имеет «% микроэкономики»