Сопоставление между 2 разными фреймами данных с промежуточными датами

#pandas #dataframe #datetime #mapping

#pandas #фрейм данных #дата и время #сопоставление

Вопрос:

Я пытаюсь сопоставить значения из 1 фрейма данных в другой, используя приведенный ниже код, он выполняет свою работу, но поскольку фреймы данных огромны (2-3 миллиона строк), для сопоставления этих значений требуется много времени. Есть ли лучший и более эффективный способ написания этого кода, который может ускорить процесс?

 for i in df.index:
    fc2 = STP[(STP['SKU'] == df.iloc[i]['SKU']) amp; (STP['EFF_DATE'] <= df.iloc[i]['Date']) amp; ((STP['END_DTTIME'] >= df.iloc[i]['Date']))]['PRICE_TYPE']
    if len(fc2.index) >0:
        df['Price_Type'].iloc[i] = fc2.values.tolist()[0]
  

Любая помощь будет высоко оценена.

 df = {'Date': ['2020-10-24', '2020-10-24', '2020-10-20', '2020-10-24', '2020-10-24'], 'SKU': [125,3245,165158,1651651,16561]}
STP = {'SKU': [125,3245,3245,165158,165158,1651651,16561], 'EDD_DATE': ['2020-10-14','2020-10-14','2020-10-24','2020-09-28','2020-06-30','2020-10-14','2020-10-14'], 'END_DATE': ['2020-10-25','2020-10-23','2020-10-31','2020-10-31','2020-09-27','2020-10-25','2020-10-25'], 'PRICE_TYPE': ['abc', 'abc', 'bca', 'abc', 'bbc', 'abc', 'bca']}

final = {'Date': ['2020-10-24', '2020-10-24', '2020-10-20', '2020-10-24', '2020-10-24'], 'SKU': [125,3245,165158,1651651,16561], 'Price_Type': ['abc', 'bca', 'abc', 'abc', 'bca']}
  

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

1. пожалуйста, покажите образец вашего ввода и ожидаемого результата, подойдет образец из 5 строк.

2. @Manakin: Я прикрепил для вас пример. Пожалуйста, сообщите. Спасибо!

3. пожалуйста, добавьте его в виде текста, изображение не воспроизводится. (я не могу скопировать его в свою среду разработки)

4. @Manakin пожалуйста, посмотрите образец в тексте.

Ответ №1:

это довольно просто в SQL, но я не знаю (хотя я уверен, что есть) о достойном подходе panda к этому, я бы подождал других ответов, но это один из способов, которым вы могли бы подойти к этому без использования циклов python.

Нам нужно будет

  1. создайте произведение обоих фреймов данных (перекрестное соединение) на основе артикула.
  2. примените логическое значение на основе дат.
  3. повторное объединение на основе артикула и даты, чтобы получить тип цены.

Настройка

 df = pd.DataFrame(df)
stp = pd.DataFrame(STP)
df['Date'] = pd.to_datetime(df['Date'])
stp['EDD_DATE'] = pd.to_datetime(stp['EDD_DATE'])
stp['END_DATE'] = pd.to_datetime(stp['END_DATE'])
  

Редактировать обработку повторяющихся левых клавиш.

 df1 = pd.merge(stp,df,on='SKU',how='outer')
m = (df1['Date'] >= df1['EDD_DATE']) amp; (df1['Date'] <= df1['END_DATE'])

df_new = pd.merge(df,df1[m].loc[:,['Date','SKU','PRICE_TYPE']]
         ,on=['SKU','Date'],how='left')


print(df)

    Date      SKU PRICE_TYPE
0 2020-10-24      125        abc
1 2020-10-24     3245        bca
2 2020-10-20   165158        abc
3 2020-10-24  1651651        abc
4 2020-10-24    16561        bca
  

Естественно, это дороже, так как вы объединяете две таблицы фактов, но это будет намного лучше и чище, чем цикл.

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

1. спасибо за решение. Это работает, если артикулы не дублируются в df, но мой набор данных имеет одинаковые артикулы для каждой даты.