Объединение фреймов данных на основе диапазона дат и идентификаторов

Я хотел бы объединить два фрейма данных, основываясь на условии, что проданный товар попадает в диапазон дат, соответствует цене и соответствует идентификатору товара. Несовпадения также необходимо сохранить и пометить как несобытие.

Данные о продажах:

Date        ID      Price
1/1/2020    3       9.99
1/1/2020    4       5.99
1/2/2020    10      69.99
1/10/2020   4       5.99
1/11/2020   3       10.99  

Рекламные данные:

Start_Date   End_Date   ID   Price  Promo
1/1/2020     1/8/2020   3    9.99   Event1
1/1/2020     1/8/2020   4    5.99   Event1
1/1/2020     1/8/2020   10   49.99  Event1

Желаемый результат:

Date        ID     Price   Promo
1/1/2020    3      9.99    Event1
1/1/2020    4      5.99    Event1
1/2/2020    10     69.99   Non-Event
1/10/2020   4      5.99    Non-Event
1/11/2020   3      10.99   Non-Event

Я застрял на этом в течение довольно долгого времени. Я пробовал несколько разных методов, включая merge_asof, numpy.piecewise и pandasql, но, похоже, в настоящее время это немного превышает мой потолок навыков. Любая помощь приветствуется.

stackoverflow.com/a/43594038/6361531
Scott Boston 22.12.2020 17:59
Почему в 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 может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
258
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Мы можем сделать merge , отфильтровать его

out = Sales.merge(Promotional, on = ['ID','Price'],how='left')
#out.Date = pd.to_datetime(out.Date)
#out.Start_Date = pd.to_datetime(out.Start_Date)
#out.End_Date = pd.to_datetime(out.End_Date)
out.loc[~(out.Date.ge(out.Start_Date)&out.Date.le(out.End_Date))|out.Promo.isnull(),'Promo'] = 'no-Event'
out = out.drop(['Start_Date','End_Date'],axis=1)
out
Out[144]: 
        Date  ID  Price     Promo
0 2020-01-01   3   9.99    Event1
1 2020-01-01   4   5.99    Event1
2 2020-01-02  10  69.99  no-Event
3 2020-01-10   4   5.99  no-Event
4 2020-01-11   3  10.99  no-Event

Арг!!! Вы снова сменили имя и имидж! Счастливых праздников! Надеюсь, вы и ваши близкие в безопасности и остаетесь здоровыми.

Scott Boston 22.12.2020 18:01

@ScottBoston, с праздником, чувак, береги себя~

BENY 22.12.2020 18:05

Блестящий. Спасибо вам обоим!

stupideye 23.12.2020 16:08

Если ваши кадры данных слишком велики, вы можете использовать декартово соединение, используя merge и how='left', а затем отфильтровать фрейм данных по дате между датой начала и окончания, используя query.

df_sales['Promo'] = df_sales.merge(df_promo, on='ID', how='left')\
                            .query('Start_Date <= Date <= End_Date')['Promo']
df_sales['Promo'] = df_sales['Promo'].fillna('Non-event')
print(df_sales)

Выход:

        Date  ID  Price      Promo
0 2020-01-01   3   9.99     Event1
1 2020-01-01   4   5.99     Event1
2 2020-01-02  10  69.99     Event1
3 2020-01-10   4   5.99  Non-event
4 2020-01-11   3  10.99  Non-event

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