Вы можете сделать это, используя декартово объединение и фильтрацию, если ваши кадры данных слишком велики:
(df1.assign(key=1)
.merge(df2.query('EmploymentType == "Employee" and EmpStatus=="Active"').assign(key=1),
on='key')
.query('EmpStartDate <= StartDate')
.groupby('StartDate')['key'].count())
Вывод:
StartDate
2013-01-01 2
2013-02-01 2
2014-04-01 4
2014-11-01 4
2015-05-01 4
Name: key, dtype: int64
Подробности:
- Отфильтруйте df2, используя
query
, чтобы включить EmploymentType и EmpStatus, равные Employee и Active соответственно. - Назначьте фиктивный ключ каждому фрейму данных и используйте
merge
на фиктивном ключе для создания декартового объединения всех записей. - Используйте
query
для фильтрации результатов объединения только с теми записями, где EmpStartDate меньше или равен StartDate. - И наконец,
groupby
StartDate и count
.
Также обратите внимание, что использование query
является ярлыком.Если имена ваших столбцов содержат специальные символы или пробел, то вам нужно отфильтровать свои фреймы данных, используя логическое индексирование.
Опция № 2:
pd.merge_asof(df2.query('EmploymentType == "Employee" and EmpStatus == "Active"').sort_values('EmpStartDate'),
df1.sort_values('StartDate'),
left_on='EmpStartDate',
right_on='StartDate',
direction='forward')\
.groupby('StartDate')['EmploymentType'].count()\
.reindex(df1.StartDate.sort_values())\
.cumsum()\
.ffill()
Вывод:
StartDate
2013-01-01 2.0
2013-02-01 2.0
2014-04-01 4.0
2014-11-01 4.0
2015-05-01 4.0
Name: EmploymentType, dtype: float64
Подробности:
Использовать pd.merge_asof
, чтобы присоединитьсяОтфильтруйте df2 до df1 до ближайшей прогнозной даты.
groupby
дата начала, объединенная с df1 и отсчета.
reindex
результаты по df.startdate для заполнения отсутствующего / нулевого значения для дат начала - Использование
cumsum
для имитации <= функциональности и суммы. </li> - Использование
fillna
для заполнения отсутствующих записей предыдущимисуммы.