Хорошо, наконец-то я понял!
Объединение (LEFT JOIN) по коду и SG
df_group = pd.merge(df1,df2, on=['Code','SG'], how='left', suffixes=('','_result'))
Создание фильтра для более низких дат
df_group['lower_date_mask'] = df_group['Date_result'] <= df_group['Date']
Фильтрация столбец Coef с NaN.
df_group.loc[df_group['lower_date_mask'] == False,'lower_date_mask'] = np.nan
df_group['Coef'] = df_group['Coef'] * df_group['lower_date_mask']
Здесь мы назначаем бесконечное значение True, чтобы избежать ошибки Pandas при выполнении функции .prod()
с NaN
df_group.loc[df_group['lower_date_mask'] == 1.0,'lower_date_mask'] = np.inf
Проблема Github по поводу функции агрегирования с nan: https://github.com/pandas-dev/pandas/issues/20824
Агрегирование с помощью .prod ()
df_group = df_group.groupby(['Code','SG','Date']).prod()
Создание окончательного фрейма данных
df_group.reset_index(inplace = True)
df_group.loc[df_group['lower_date_mask'] == 1.0,'Coef'] = np.nan
df_group.drop(columns = ['lower_date_mask'],inplace = True)
Окончательный вывод
Code SG Date Coef
0 Code1 SG1 2020-02-01 0.50
1 Code1 SG1 2020-03-01 0.35
2 Code2 SG2 2020-01-01 NaN
3 Code3 SG3 2020-02-01 0.30
4 Code4 SG3 2020-02-01 NaN
Стоит сказать, что вы можете добиться этого с помощью функции .apply()
, однако это замедлит вас, если ваш DataFrame станет больше.
Надеюсь, я смогу помочь! Мне потребовалось буквально два часа, чтобы продумать этот код!
EDIT :
Как упоминал @codesensei, в его базе данных есть другие столбцы, которые составляют комбинацию ['Code','SG','Date']
не уникальный. В этом случае есть два возможных способа справиться с этим. Во-первых, если в df1 или df2 есть другие столбцы, которые делают комбинацию уникальной, просто добавьте их в группу, например:
df_group = df_group.groupby(['Code','SG','Date','column_of_interest']).prod()
Во-вторых, если проще сделать комбинацию уникальной каким-то образом идентификатора, скажем, индекса df1, вы можете сделать:
df1.reset_index(inplace = True)
# merge dataframes and follow the other steps as stated earlier in this answer
df_group = df_group.groupby(['Code','SG','Date','index']).prod()
Если хотите, вы можете переименовать 'index' во что-нибудь другое, просто чтобы сделать его более явным.
Надеюсь, что смогу помочь!