Фильтрация фрейма данных на основе значения столбца другого фрейма данных

У меня 2 фрейма данных

df1

Company           SKU   Sales
Walmart           A     100
Total             A     200
Walmart           B     200
Total             B     300
Walmart           C     400
Walmart           D     500

df2

 Company             SKU   Sales
 Walmart             A     400
 Total               B     300
 Walmart             C     900
 Walmart             F     400
 Total               G     500

Мне нужен результирующий фрейм данных (df2), в котором есть только записи совпадающих SKU в df1 и df2

df2

Company       SKU   Sales 
Walmart       A     400
Total         B     300
Walmart       C     900

Мне нужны только уникальные (Компания + SKU) значения df1 в df2

Есть ли хорошее решение для этого?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
4
0
17 160
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Обновлять

Вы можете использовать простую маску:

m = df2.SKU.isin(df1.SKU)
df2 = df2[m]

Вы ищете внутреннего соединения. Попробуй это:

df3 = df1.merge(df2, on=['SKU','Sales'], how='inner')

#  SKU  Sales
#0   A    100
#1   B    200
#2   C    300

Или это:

df3 = df1.merge(df2, on='SKU', how='inner')

#  SKU  Sales_x  Sales_y
#0   A      100      100
#1   B      200      200
#2   C      300      300

Привет, Антон, спасибо за ответ. Покупка продаж - это не мой ключ. Это может быть любое значение.

Moses Soleman 02.06.2018 11:31

@AhamedMoosa Я не совсем понимаю, чего вы хотите. Предлагаемое мной решение дает желаемый результат. Хорошо, извини, что ты изменил имя

Anton vBR 02.06.2018 11:46

Ваш обновленный ответ соответствует моей цели Спасибо. Могу ли я использовать isin для нескольких столбцов?

Moses Soleman 02.06.2018 12:01

@AhamedMoosa Извините за поздний ответ. Вы все еще ищете ответ, как это сделать в нескольких столбцах?

Anton vBR 12.06.2018 17:48

Я уже нашел обходной путь для этой проблемы, я использовал ваше решение и немного импровизировал для своего варианта использования. Спасибо.

Moses Soleman 12.06.2018 18:02

@AhamedMoosa Отлично :)

Anton vBR 12.06.2018 18:04

Решение 1:

# First identify the common SKU's    
temp = list(set(list(df1.SKU)).intersection(set(list(df2.SKU))))

# Filter df2 using the list of common SKU's
df3 = df2[df2.SKU.isin(temp)]
print(df3)

   SKU  Sales
0   A   400
1   B   300
2   C   900

Решение 2. Однострочное решение

df3 = df2[df2.SKU.isin(list(df1.SKU))]

РЕДАКТИРОВАТЬ 1: Решение для обновленного вопроса (не оптимальный способ сделать это, но отвечает на ваш вопрос)

# reading data for df1
df1= pd.read_clipboard(sep='\\s+')
df1
    Company SKU Sales
0   Walmart A   100
1   Total   A   200
2   Walmart B   200
3   Total   B   300
4   Walmart C   400
5   Walmart D   500

# reading data for df2
df2= pd.read_clipboard(sep='\\s+')
df2
Company SKU Sales
0   Walmart A   400
1   Total   B   300
2   Walmart C   900
3   Walmart F   400
4   Total   G   500

# Using intersect and zip to create a list of tuples matching in the data frames
temp = list(set(list(zip(df1.Company,df1.SKU))).intersection(set(list(zip(df2.Company,df2.SKU)))))
temp
[('Walmart', 'A'), ('Walmart', 'C'), ('Total', 'B')]

# Creating a helper variable in df2 to lookup in the temp list
df2["temp"] = list(zip(df2.Company,df2.SKU))
df2= df2[df2["temp"].isin(temp)]
del(df2["temp"])
df2
    Company SKU Sales
0   Walmart A   400
1   Total   B   300
2   Walmart C   900

Приветствуются предложения по улучшению этого кода

Привет, баран, спасибо за ответ. На всякий случай, если мне нужно пересечь несколько столбцов?

Moses Soleman 02.06.2018 12:02

Затем вы можете перейти к Решению 1, так как temp - это список, который вы можете пересечь с другим списком.

Ram 02.06.2018 12:15

Привет, Рам, я отредактировал свой вопрос, пожалуйста, сообщите, может ли ваше первое решение достичь этого

Moses Soleman 02.06.2018 13:10

На мой взгляд, преобразование list() не нужно и потенциально дорого.

jpp 03.06.2018 16:40

Полностью с тобой согласен. Спасибо!

Ram 03.06.2018 16:58

Один из способов - выровнять индексы, а затем использовать маску.

# align indices
df1 = df1.set_index(['Company',  'SKU'])
df2 = df2.set_index(['Company',  'SKU'])

# calculate & apply mask
df2 = df2[df2.index.isin(df1.index)].reset_index()

Сброс индекса не требуется, но необходим для поднятия Company и SKU до столбцов.

Спасибо, jpp, я сделал то же самое. Я объединил столбцы компании и SKU, а затем применил маску.

Moses Soleman 03.06.2018 17:06

Другие вопросы по теме