Сравните столбцы двух информационных фреймов, не объединяя их - PullRequest
0 голосов
/ 24 октября 2018

У меня есть два кадра данных DF1 и DF2.

DF1:

StartDate

1/1/2013
2/1/2013
11/1/2014
4/1/2014
5/1/2015

DF2:

EmploymentType        EmpStatus           EmpStartDate

Employee              Active              11/5/2012
Employee              Active              9/10/2012
Employee              Active              10/15/2013
Employee              Active              10/29/2013
Employee              Terminated          10/29/2013
Contractor            Terminated          11/20/2014
Contractor            Active              11/20/2014

Я хочу количество строк из DF2, где EmploymentType = 'Employee' и EmpStatus = 'Active' и EmpStartDate <= Дата начала DF1 </p>

Вывод:

Start Date    Count

1/1/2013      2
2/1/2013      2
11/1/2014     4
4/1/2014      4
5/1/2015      4

Как мне добиться этого без объединения двух фреймов данных?

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

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

def compensation(x):
return DF2[DF2['EmpStartDate']<x
 and  DF2['EmpStatus']=='Active'].shape[0]

DF1['Count']=DF1['StartDate']
       .apply(lambda x:  
                   compensation(x),axis=1)

Метод - логическое индексирование и подсчет строк.https://pandas.pydata.org/pandas-docs/stable/indexing.html

0 голосов
/ 24 октября 2018

Вы можете сделать это, используя декартово объединение и фильтрацию, если ваши кадры данных слишком велики:

(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 для заполнения отсутствующих записей предыдущимисуммы.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...